// 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 "MDCChipView.h"
#import "private/MDCChipView+Private.h"

#import "UIView+MaterialElevationResponding.h"
#import "MDCInkView.h"
#import "MDCRippleView.h"
#import "MDCShadow.h"
#import "MDCShadowsCollection.h"
#import "MDCShadowElevations.h"
#import "MDCRoundedCornerTreatment.h"
#import "MDCRectangleShapeGenerator.h"
#import "MDCShapeMediator.h"
#import "MDCShapedShadowLayer.h"
#import "MDCFontTextStyle.h"
#import "MDCTypography.h"
#import "UIFont+MaterialScalable.h"
#import "UIFont+MaterialTypography.h"
#import "MDCMath.h"
#import <MDFInternationalization/MDFInternationalization.h>  // IWYU pragma: keep
#import <MDFInternationalization/MDFRTL.h>

static const MDCFontTextStyle kTitleTextStyle = MDCFontTextStyleBody2;

// KVO context
static char *const kKVOContextMDCChipView = "kKVOContextMDCChipView";

static const CGSize kMDCChipMinimumSizeDefault = (CGSize){(CGFloat)0, (CGFloat)32};

// Creates a UIColor from a 24-bit RGB color encoded as an integer.
static inline UIColor *MDCColorFromRGB(uint32_t rgbValue) {
  return [UIColor colorWithRed:((CGFloat)((rgbValue & 0xFF0000) >> 16)) / 255
                         green:((CGFloat)((rgbValue & 0x00FF00) >> 8)) / 255
                          blue:((CGFloat)((rgbValue & 0x0000FF) >> 0)) / 255
                         alpha:1];
}

static inline UIColor *MDCColorDarken(UIColor *color, CGFloat percent) {
  CGFloat hue;
  CGFloat saturation;
  CGFloat brightness;
  CGFloat alpha;
  [color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];

  brightness = MIN(1, MAX(0, brightness - percent));

  return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha];
}

static inline UIColor *MDCColorLighten(UIColor *color, CGFloat percent) {
  return MDCColorDarken(color, -percent);
}

// TODO(samnm): Pull background color from MDCPalette
static const uint32_t MDCChipBackgroundColor = 0xEBEBEB;
static const CGFloat MDCChipSelectedDarkenPercent = (CGFloat)0.16;
static const CGFloat MDCChipDisabledLightenPercent = (CGFloat)0.38;
static const CGFloat MDCChipTitleColorWhite = (CGFloat)0.13;
static const CGFloat MDCChipTitleColorDisabledLightenPercent = (CGFloat)0.38;

static const UIEdgeInsets MDCChipContentPadding = {4, 4, 4, 4};
static const UIEdgeInsets MDCChipImagePadding = {0, 0, 0, 0};
static const UIEdgeInsets MDCChipTitlePadding = {3, 8, 4, 8};
static const UIEdgeInsets MDCChipAccessoryPadding = {0, 0, 0, 0};

static CGRect CGRectVerticallyCentered(CGRect rect,
                                       UIEdgeInsets padding,
                                       CGFloat height,
                                       CGFloat pixelScale) {
  CGFloat viewHeight = CGRectGetHeight(rect) + padding.top + padding.bottom;
  CGFloat yValue = (height - viewHeight) / 2;
  yValue = round(yValue * pixelScale) / pixelScale;
  return CGRectOffset(rect, 0, yValue);
}

static inline CGRect MDCChipBuildFrame(
    UIEdgeInsets insets, CGSize size, CGPoint originPoint, CGFloat chipHeight, CGFloat pixelScale) {
  CGRect frame =
      CGRectMake(originPoint.x + insets.left, originPoint.y + insets.top, size.width, size.height);
  return CGRectVerticallyCentered(frame, insets, chipHeight, pixelScale);
}

static inline CGFloat UIEdgeInsetsHorizontal(UIEdgeInsets insets) {
  return insets.left + insets.right;
}

static inline CGFloat UIEdgeInsetsVertical(UIEdgeInsets insets) {
  return insets.top + insets.bottom;
}

static inline CGSize CGSizeExpandWithInsets(CGSize size, UIEdgeInsets edgeInsets) {
  return CGSizeMake(size.width + UIEdgeInsetsHorizontal(edgeInsets),
                    size.height + UIEdgeInsetsVertical(edgeInsets));
}

static inline CGSize CGSizeShrinkWithInsets(CGSize size, UIEdgeInsets edgeInsets) {
  return CGSizeMake(size.width - UIEdgeInsetsHorizontal(edgeInsets),
                    size.height - UIEdgeInsetsVertical(edgeInsets));
}

@interface MDCChipView ()
@property(nonatomic, readonly) CGRect contentRect;
@property(nonatomic, readonly, strong) MDCShapedShadowLayer *layer;
@property(nonatomic, readonly) BOOL showImageView;
@property(nonatomic, readonly) BOOL showSelectedImageView;
@property(nonatomic, readonly) BOOL showAccessoryView;
@property(nonatomic, assign) BOOL shouldFullyRoundCorner;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@property(nonatomic, strong) MDCInkView *inkView;
#pragma clang diagnostic pop
@property(nonatomic, strong) MDCRippleView *rippleView;
@property(nonatomic, strong, nonnull) NSMutableDictionary<NSNumber *, UIColor *> *rippleColors;
@property(nonatomic, readonly) CGFloat pixelScale;
@property(nonatomic, assign) BOOL enableRippleBehavior;
@property(nonatomic, assign) UIEdgeInsets currentVisibleAreaInsets;
@property(nonatomic, assign) CGFloat currentCornerRadius;
@end

@implementation MDCChipView {
  // For each UIControlState.
  NSMutableDictionary<NSNumber *, UIColor *> *_backgroundColors;
  NSMutableDictionary<NSNumber *, UIColor *> *_borderColors;
  NSMutableDictionary<NSNumber *, NSNumber *> *_borderWidths;
  NSMutableDictionary<NSNumber *, NSNumber *> *_elevations;
  NSMutableDictionary<NSNumber *, UIColor *> *_inkColors;
  NSMutableDictionary<NSNumber *, UIColor *> *_shadowColors;
  NSMutableDictionary<NSNumber *, UIColor *> *_tintColors;
  NSMutableDictionary<NSNumber *, UIColor *> *_titleColors;

  UIFont *_titleFont;

  BOOL _mdc_adjustsFontForContentSizeCategory;
  MDCShapeMediator *_shapedLayer;
  CGFloat _currentElevation;
}

static BOOL gEnablePerformantShadow = NO;

@synthesize mdc_overrideBaseElevation = _mdc_overrideBaseElevation;
@synthesize mdc_elevationDidChangeBlock = _mdc_elevationDidChangeBlock;
@synthesize cornerRadius = _cornerRadius;
@synthesize shadowsCollection = _shadowsCollection;

@dynamic layer;

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

- (void)commonMDCChipViewInit {
  _minimumSize = kMDCChipMinimumSizeDefault;
  self.isAccessibilityElement = YES;
  self.accessibilityTraits = UIAccessibilityTraitButton;
  self.imageViewSize = CGSizeZero;
  _mdc_overrideBaseElevation = -1;
  _currentElevation = 0;
  if (gEnablePerformantShadow) {
    _shapedLayer = [[MDCShapeMediator alloc] initWithViewLayer:self.layer];
  }
  [self addObservers];
}

- (instancetype)initWithFrame:(CGRect)frame {
  if (self = [super initWithFrame:frame]) {
    if (!_backgroundColors) {
      // _backgroundColors may have already been initialized by setting the backgroundColor setter.
      UIColor *normal = MDCColorFromRGB(MDCChipBackgroundColor);
      UIColor *disabled = MDCColorLighten(normal, MDCChipDisabledLightenPercent);
      UIColor *selected = MDCColorDarken(normal, MDCChipSelectedDarkenPercent);
      UIColor *selectedDisabled = MDCColorFromRGB(MDCChipBackgroundColor);

      _backgroundColors = [NSMutableDictionary dictionary];
      _backgroundColors[@(UIControlStateNormal)] = normal;
      _backgroundColors[@(UIControlStateDisabled)] = disabled;
      _backgroundColors[@(UIControlStateSelected)] = selected;
      _backgroundColors[@(UIControlStateSelected & UIControlStateDisabled)] = selectedDisabled;
    }
    _borderColors = [NSMutableDictionary dictionary];
    _borderWidths = [NSMutableDictionary dictionary];

    _elevations = [NSMutableDictionary dictionary];
    _elevations[@(UIControlStateNormal)] = @(0);
    _elevations[@(UIControlStateHighlighted)] = @(MDCShadowElevationRaisedButtonPressed);
    _elevations[@(UIControlStateHighlighted | UIControlStateSelected)] =
        @(MDCShadowElevationRaisedButtonPressed);

    _inkColors = [NSMutableDictionary dictionary];

    _tintColors = [NSMutableDictionary dictionary];

    UIColor *titleColor = [UIColor colorWithWhite:MDCChipTitleColorWhite alpha:1];
    _titleColors = [NSMutableDictionary dictionary];
    _titleColors[@(UIControlStateNormal)] = titleColor;
    _titleColors[@(UIControlStateDisabled)] =
        MDCColorLighten(titleColor, MDCChipTitleColorDisabledLightenPercent);

    _shadowColors = [NSMutableDictionary dictionary];
    _shadowColors[@(UIControlStateNormal)] = [UIColor blackColor];

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    _inkView = [[MDCInkView alloc] initWithFrame:self.bounds];
#pragma clang diagnostic pop
    _inkView.usesLegacyInkRipple = NO;
    _inkView.inkColor = [self inkColorForState:UIControlStateNormal];
    [self addSubview:_inkView];

    _rippleView = [[MDCRippleView alloc] initWithFrame:self.bounds];
    _rippleView.rippleColor = [self rippleColorForState:UIControlStateNormal];
    _rippleColors = [NSMutableDictionary dictionary];

    _imageView = [[UIImageView alloc] init];
    [self addSubview:_imageView];

    _selectedImageView = [[UIImageView alloc] init];
    [self addSubview:_selectedImageView];

    _titleLabel = [[UILabel alloc] init];
    // If we are using the default (system) font loader, retrieve the
    // font from the UIFont standardFont API.
    if ([MDCTypography.fontLoader isKindOfClass:[MDCSystemFontLoader class]]) {
      _titleLabel.font = [UIFont mdc_standardFontForMaterialTextStyle:kTitleTextStyle];
    } else {
      // There is a custom font loader, retrieve the font from it.
      _titleLabel.font = [MDCTypography buttonFont];
    }
    _titleLabel.textAlignment = NSTextAlignmentCenter;
    [self addSubview:_titleLabel];

    _contentPadding = MDCChipContentPadding;
    _imagePadding = MDCChipImagePadding;
    _titlePadding = MDCChipTitlePadding;
    _accessoryPadding = MDCChipAccessoryPadding;
    _currentVisibleAreaInsets = UIEdgeInsetsZero;
    _currentCornerRadius = 0.0f;
    _centerVisibleArea = NO;

    if (!gEnablePerformantShadow) {
      self.layer.elevation = [self elevationForState:UIControlStateNormal];
    }
    self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

    self.shouldFullyRoundCorner = YES;

    [self updateBackgroundColor];

    [self commonMDCChipViewInit];
  }
  return self;
}

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

- (void)dealloc {
  [self removeObservers];
  [self removeTarget:self action:NULL forControlEvents:UIControlEventAllEvents];
}

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
  [super traitCollectionDidChange:previousTraitCollection];
  if (self.traitCollectionDidChangeBlock) {
    self.traitCollectionDidChangeBlock(self, previousTraitCollection);
  }
}

- (void)setShapeGenerator:(id<MDCShapeGenerating>)shapeGenerator {
  if (!UIEdgeInsetsEqualToEdgeInsets(self.visibleAreaInsets, UIEdgeInsetsZero)) {
    // When visibleAreaInsets is not UIEdgeInsetsZero, the custom shapeGenerater should not be set
    // through setter.
    return;
  }

  [self configureLayerWithShapeGenerator:shapeGenerator];

  if (!shapeGenerator && !self.shouldFullyRoundCorner) {
    [self configureLayerWithCornerRadius:self.cornerRadius];
  }
  [self setNeedsLayout];
}

- (void)configureLayerWithShapeGenerator:(id<MDCShapeGenerating>)shapeGenerator {
  if (gEnablePerformantShadow) {
    _shapedLayer.shapeGenerator = shapeGenerator;
  } else {
    self.layer.shapeGenerator = shapeGenerator;
  }

  if (shapeGenerator) {
    self.layer.cornerRadius = 0;
    self.layer.shadowPath = nil;
  }

  [self updateBackgroundColor];
}

- (id)shapeGenerator {
  if (gEnablePerformantShadow) {
    return _shapedLayer.shapeGenerator;
  }
  return self.layer.shapeGenerator;
}

- (void)configureLayerWithCornerRadius:(CGFloat)cornerRadius {
  if (!self.shapeGenerator &&
      UIEdgeInsetsEqualToEdgeInsets(self.visibleAreaInsets, UIEdgeInsetsZero)) {
    self.layer.cornerRadius = cornerRadius;
    if (gEnablePerformantShadow) {
      [self updateShadow];
    } else {
      self.layer.shadowPath =
          [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:cornerRadius].CGPath;
    }
  } else if (!UIEdgeInsetsEqualToEdgeInsets(self.visibleAreaInsets, UIEdgeInsetsZero)) {
    [self configureLayerWithVisibleAreaInsets:self.visibleAreaInsets cornerRadius:cornerRadius];
  }
}

- (void)configureLayerWithVisibleAreaInsets:(UIEdgeInsets)visibleAreaInsets
                               cornerRadius:(CGFloat)cornerRadius {
  if (UIEdgeInsetsEqualToEdgeInsets(visibleAreaInsets, self.currentVisibleAreaInsets) &&
      MDCCGFloatEqual(self.currentCornerRadius, cornerRadius)) {
    return;
  }

  self.currentVisibleAreaInsets = visibleAreaInsets;
  self.currentCornerRadius = cornerRadius;

  MDCRectangleShapeGenerator *shapeGenerator = [[MDCRectangleShapeGenerator alloc] init];
  MDCCornerTreatment *cornerTreatment =
      [[MDCRoundedCornerTreatment alloc] initWithRadius:cornerRadius];
  [shapeGenerator setCorners:cornerTreatment];
  shapeGenerator.topLeftCornerOffset = CGPointMake(visibleAreaInsets.left, visibleAreaInsets.top);
  shapeGenerator.topRightCornerOffset =
      CGPointMake(-visibleAreaInsets.right, visibleAreaInsets.top);
  shapeGenerator.bottomLeftCornerOffset =
      CGPointMake(visibleAreaInsets.left, -visibleAreaInsets.bottom);
  shapeGenerator.bottomRightCornerOffset =
      CGPointMake(-visibleAreaInsets.right, -visibleAreaInsets.bottom);

  [self configureLayerWithShapeGenerator:shapeGenerator];
}

- (void)setCornerRadius:(CGFloat)cornerRadius {
  _cornerRadius = cornerRadius;
  // When cornerRadius is set to a custom value, corner is not forced to be fully rounded.
  self.shouldFullyRoundCorner = NO;

  [self configureLayerWithCornerRadius:cornerRadius];
}

- (CGFloat)cornerRadius {
  if (!self.shouldFullyRoundCorner) {
    return _cornerRadius;
  }
  return self.layer.cornerRadius;
}

- (void)setEnableRippleBehavior:(BOOL)enableRippleBehavior {
  _enableRippleBehavior = enableRippleBehavior;

  if (enableRippleBehavior) {
    [self.inkView removeFromSuperview];
    self.rippleView.frame = self.bounds;
    [self insertSubview:self.rippleView belowSubview:self.imageView];
  } else {
    [self.rippleView removeFromSuperview];
    [self insertSubview:self.inkView belowSubview:self.imageView];
  }
}

- (void)setDisableInkAndRippleBehavior:(BOOL)disableInkAndRippleBehavior {
  _disableInkAndRippleBehavior = disableInkAndRippleBehavior;
  [self.inkView removeFromSuperview];
  [self.rippleView removeFromSuperview];
}

#pragma mark - Dynamic Type Support

- (BOOL)mdc_adjustsFontForContentSizeCategory {
  return _mdc_adjustsFontForContentSizeCategory;
}

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

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

  [self updateTitleFont];
}

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

#pragma mark - Property support

- (void)setAccessoryView:(UIView *)accessoryView {
  [_accessoryView removeFromSuperview];
  _accessoryView = accessoryView;
  if (accessoryView) {
    [self insertSubview:accessoryView aboveSubview:_titleLabel];
  }
}

- (nullable UIColor *)backgroundColorForState:(UIControlState)state {
  UIColor *backgroundColor = _backgroundColors[@(state)];
  if (!backgroundColor && state != UIControlStateNormal) {
    backgroundColor = _backgroundColors[@(UIControlStateNormal)];
  }
  return backgroundColor;
}

- (void)setBackgroundColor:(nullable UIColor *)backgroundColor forState:(UIControlState)state {
  // Since setBackgroundColor can be called in the initializer we need to optionally build the dict.
  if (!_backgroundColors) {
    _backgroundColors = [NSMutableDictionary dictionary];
  }
  _backgroundColors[@(state)] = backgroundColor;

  [self updateBackgroundColor];
}

- (UIColor *)backgroundColor {
  return gEnablePerformantShadow ? _shapedLayer.shapedBackgroundColor
                                 : self.layer.shapedBackgroundColor;
}

- (void)updateBackgroundColor {
  if (gEnablePerformantShadow) {
    _shapedLayer.shapedBackgroundColor = [self backgroundColorForState:self.state];
  } else {
    self.layer.shapedBackgroundColor = [self backgroundColorForState:self.state];
  }
}

- (nullable UIColor *)borderColorForState:(UIControlState)state {
  UIColor *borderColor = _borderColors[@(state)];
  if (!borderColor && state != UIControlStateNormal) {
    borderColor = _borderColors[@(UIControlStateNormal)];
  }
  return borderColor;
}

- (void)setBorderColor:(nullable UIColor *)borderColor forState:(UIControlState)state {
  _borderColors[@(state)] = borderColor;

  [self updateBorderColor];
}

- (void)updateBorderColor {
  if (gEnablePerformantShadow) {
    _shapedLayer.shapedBorderColor = [self borderColorForState:self.state];
  } else {
    self.layer.shapedBorderColor = [self borderColorForState:self.state];
  }
}

- (CGFloat)borderWidthForState:(UIControlState)state {
  NSNumber *borderWidth = _borderWidths[@(state)];
  if (borderWidth == nil && state != UIControlStateNormal) {
    borderWidth = _borderWidths[@(UIControlStateNormal)];
  }
  if (borderWidth != nil) {
    return (CGFloat)borderWidth.doubleValue;
  }
  return 0;
}

- (void)setBorderWidth:(CGFloat)borderWidth forState:(UIControlState)state {
  _borderWidths[@(state)] = @(borderWidth);

  [self updateBorderWidth];
}

- (void)updateBorderWidth {
  if (gEnablePerformantShadow) {
    _shapedLayer.shapedBorderWidth = [self borderWidthForState:self.state];
  } else {
    self.layer.shapedBorderWidth = [self borderWidthForState:self.state];
  }
}

- (CGFloat)mdc_currentElevation {
  return _currentElevation;
}

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

- (CGFloat)elevationForState:(UIControlState)state {
  NSNumber *elevation = _elevations[@(state)];
  if (elevation == nil && state != UIControlStateNormal) {
    elevation = _elevations[@(UIControlStateNormal)];
  }
  if (elevation != nil) {
    return (CGFloat)[elevation doubleValue];
  }
  return 0;
}

- (void)setElevation:(CGFloat)elevation forState:(UIControlState)state {
  _elevations[@(state)] = @(elevation);

  [self updateElevation];
}

- (void)updateElevation {
  CGFloat newElevation = [self elevationForState:self.state];
  if (!MDCCGFloatEqual(self.mdc_currentElevation, newElevation)) {
    _currentElevation = newElevation;
    if (gEnablePerformantShadow) {
      [self updateShadow];
    } else {
      self.layer.elevation = newElevation;
    }
    [self mdc_elevationDidChange];
  }
}

- (void)updateShadow {
  if (_shapedLayer.shapeGenerator == nil) {
    MDCShadow *shadow = [self.shadowsCollection shadowForElevation:self.mdc_currentElevation];
    shadow = [[MDCShadowBuilder
        builderWithColor:[self shadowColorForState:self.state] ?: MDCShadowColor()
                 opacity:shadow.opacity
                  radius:shadow.radius
                  offset:shadow.offset
                  spread:shadow.spread] build];
    MDCConfigureShadowForView(self, shadow);
  } else {
    MDCShadow *shadow = [self.shadowsCollection shadowForElevation:self.mdc_currentElevation];
    shadow = [[MDCShadowBuilder
        builderWithColor:[self shadowColorForState:self.state] ?: MDCShadowColor()
                 opacity:shadow.opacity
                  radius:shadow.radius
                  offset:shadow.offset
                  spread:shadow.spread] build];
    MDCConfigureShadowForViewWithPath(self, shadow, self.layer.shadowPath);
  }
}

- (UIColor *)inkColorForState:(UIControlState)state {
  UIColor *inkColor = _inkColors[@(state)];
  if (!inkColor && state != UIControlStateNormal) {
    inkColor = _inkColors[@(UIControlStateNormal)];
  }
  return inkColor;
}

- (void)setInkColor:(UIColor *)inkColor forState:(UIControlState)state {
  _inkColors[@(state)] = inkColor;

  [self updateInkColor];

  // Set Ripple color as well when using the Ink API.
  [self setRippleColor:inkColor forState:state];
}

- (void)updateInkColor {
  UIColor *inkColor = [self inkColorForState:self.state];
  self.inkView.inkColor = inkColor ?: self.inkView.defaultInkColor;
}

- (UIColor *)rippleColorForState:(UIControlState)state {
  UIColor *rippleColor = self.rippleColors[@(state)];
  if (!rippleColor && state != UIControlStateNormal) {
    rippleColor = self.rippleColors[@(UIControlStateNormal)];
  }
  return rippleColor;
}

- (void)setRippleColor:(UIColor *)rippleColor forState:(UIControlState)state {
  _rippleColors[@(state)] = rippleColor;

  [self updateRippleColor];
}

- (void)updateRippleColor {
  UIColor *rippleColor = [self rippleColorForState:self.state];
  self.rippleView.rippleColor = rippleColor ?: self.inkView.defaultInkColor;
}

- (nullable UIColor *)shadowColorForState:(UIControlState)state {
  UIColor *shadowColor = _shadowColors[@(state)];
  if (!shadowColor && state != UIControlStateNormal) {
    shadowColor = _shadowColors[@(UIControlStateNormal)];
  }
  return shadowColor;
}

- (void)setShadowColor:(nullable UIColor *)shadowColor forState:(UIControlState)state {
  _shadowColors[@(state)] = shadowColor;

  [self updateShadowColor];
}

- (void)updateShadowColor {
  self.layer.shadowColor = [self shadowColorForState:self.state].CGColor;
}

- (nullable UIColor *)tintColorForState:(UIControlState)state {
  UIColor *tintColor = _tintColors[@(state)];

  return tintColor;
}

- (nullable UIFont *)titleFont {
  return _titleFont;
}

- (void)setTitleFont:(nullable UIFont *)titleFont {
  _titleFont = titleFont;

  [self updateTitleFont];
}

- (nullable UIColor *)titleColorForState:(UIControlState)state {
  UIColor *titleColor = _titleColors[@(state)];
  if (!titleColor && state != UIControlStateNormal) {
    titleColor = _titleColors[@(UIControlStateNormal)];
  }
  return titleColor;
}

- (void)setTitleColor:(nullable UIColor *)titleColor forState:(UIControlState)state {
  _titleColors[@(state)] = titleColor;

  [self updateTitleColor];
}

- (void)setTintColor:(nullable UIColor *)tintColor forState:(UIControlState)state {
  _tintColors[@(state)] = tintColor;
  [self updateTintColor];
}

- (void)setContentHorizontalAlignment:(UIControlContentHorizontalAlignment)alignment {
  [super setContentHorizontalAlignment:alignment];
  [self setNeedsLayout];
}

- (void)updateTitleFont {
  // If we have a custom font apply it to the label.
  // If not, fall back to the Material specified font.
  UIFont *titleFont = _titleFont ?: [[self class] defaultTitleFont];

  // If we are automatically adjusting for Dynamic Type resize the font based on the text style
  if (self.mdc_adjustsFontForContentSizeCategory) {
    if (titleFont.mdc_scalingCurve) {
      titleFont = [titleFont mdc_scaledFontForTraitEnvironment:self];
    } else {
      titleFont =
          [titleFont mdc_fontSizedForMaterialTextStyle:kTitleTextStyle
                                  scaledForDynamicType:_mdc_adjustsFontForContentSizeCategory];
    }
  }
  self.titleLabel.font = titleFont;

  [self setNeedsLayout];
}

+ (UIFont *)defaultTitleFont {
  // TODO(#2709): Migrate to a single source of truth for fonts
  if ([MDCTypography.fontLoader isKindOfClass:[MDCSystemFontLoader class]]) {
    return [UIFont mdc_standardFontForMaterialTextStyle:kTitleTextStyle];
  }
  return [MDCTypography buttonFont];
}

- (void)updateTintColor {
  UIColor *tintColor = [self tintColorForState:self.state];

  if (tintColor != nil) {
    self.imageView.tintColor = tintColor;
    self.selectedImageView.tintColor = tintColor;
    self.accessoryView.tintColor = tintColor;
  }
}

- (void)updateTitleColor {
  self.titleLabel.textColor = [self titleColorForState:self.state];
}

- (void)updateAccessibility {
  // Clearing and then adding the relevant traits based on current the state (while accommodating
  // concurrent states).
  self.accessibilityTraits &= ~(UIAccessibilityTraitSelected | UIAccessibilityTraitNotEnabled);

  if ((self.state & UIControlStateSelected) == UIControlStateSelected) {
    self.accessibilityTraits |= UIAccessibilityTraitSelected;
  }

  if ((self.state & UIControlStateDisabled) == UIControlStateDisabled) {
    self.accessibilityTraits |= UIAccessibilityTraitNotEnabled;
  }
}

- (NSString *)accessibilityLabel {
  NSString *accessibilityLabel = [super accessibilityLabel];
  if (accessibilityLabel.length > 0) {
    return accessibilityLabel;
  }
  accessibilityLabel = self.titleLabel.accessibilityLabel;
  if (accessibilityLabel.length > 0) {
    return accessibilityLabel;
  }
  return self.titleLabel.text;
}

- (void)updateState {
  [self updateBackgroundColor];
  [self updateBorderColor];
  [self updateBorderWidth];
  [self updateElevation];
  [self updateInkColor];
  [self updateRippleColor];
  [self updateShadowColor];
  [self updateTitleFont];
  [self updateTitleColor];
  [self updateAccessibility];
  [self updateTintColor];
}

#pragma mark - Key-value observing

- (void)addObservers {
  for (NSString *keyPath in [self titleLabelKVOKeyPaths]) {
    [self.titleLabel addObserver:self
                      forKeyPath:keyPath
                         options:NSKeyValueObservingOptionNew
                         context:kKVOContextMDCChipView];
  }
  [self.imageView addObserver:self
                   forKeyPath:NSStringFromSelector(@selector(image))
                      options:NSKeyValueObservingOptionNew
                      context:kKVOContextMDCChipView];
}

- (void)removeObservers {
  for (NSString *keyPath in [self titleLabelKVOKeyPaths]) {
    [self.titleLabel removeObserver:self forKeyPath:keyPath context:kKVOContextMDCChipView];
  }
  [self.imageView removeObserver:self
                      forKeyPath:NSStringFromSelector(@selector(image))
                         context:kKVOContextMDCChipView];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSKeyValueChangeKey, id> *)change
                       context:(void *)context {
  if (context != kKVOContextMDCChipView) {
    return;
  }
  if (object == self.titleLabel) {
    NSArray<NSString *> *titleLabelKeyPaths = [self titleLabelKVOKeyPaths];
    for (NSString *titleLabelKeyPath in titleLabelKeyPaths) {
      if ([titleLabelKeyPath isEqualToString:keyPath]) {
        [self invalidateIntrinsicContentSize];
        [self setNeedsLayout];
      }
    }
  } else if (object == self.imageView) {
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(image))]) {
      [self invalidateIntrinsicContentSize];
      [self setNeedsLayout];
    }
  }
}

- (NSArray<NSString *> *)titleLabelKVOKeyPaths {
  return @[
    NSStringFromSelector(@selector(text)),
    NSStringFromSelector(@selector(font)),
  ];
}

#pragma mark - Custom touch handling

- (BOOL)pointInside:(CGPoint)point withEvent:(__unused UIEvent *)event {
  CGRect hitAreaRect = UIEdgeInsetsInsetRect(CGRectStandardize(self.bounds), self.hitAreaInsets);
  return CGRectContainsPoint(hitAreaRect, point);
}

#pragma mark - Visible area

- (UIEdgeInsets)visibleAreaInsets {
  UIEdgeInsets visibleAreaInsets = UIEdgeInsetsZero;
  if (self.centerVisibleArea) {
    CGSize visibleAreaSize = [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
    CGFloat additionalRequiredHeight =
        MAX(0, CGRectGetHeight(self.bounds) - visibleAreaSize.height);
    CGFloat additionalRequiredWidth = MAX(0, CGRectGetWidth(self.bounds) - visibleAreaSize.width);
    visibleAreaInsets.top = ceil(additionalRequiredHeight * 0.5f);
    visibleAreaInsets.bottom = additionalRequiredHeight - visibleAreaInsets.top;
    visibleAreaInsets.left = ceil(additionalRequiredWidth * 0.5f);
    visibleAreaInsets.right = additionalRequiredWidth - visibleAreaInsets.left;
  }

  return visibleAreaInsets;
}

#pragma mark - Control

- (void)setEnabled:(BOOL)enabled {
  [super setEnabled:enabled];

  [self updateState];
}

- (void)setHighlighted:(BOOL)highlighted {
  if (!self.isEnabled) {
    return;
  }

  [super setHighlighted:highlighted];

  [self updateState];
}

- (void)setSelected:(BOOL)selected {
  if (!self.isEnabled) {
    return;
  }

  [super setSelected:selected];

  [self updateState];
  [self setNeedsLayout];
}

#pragma mark - Layout

- (void)layoutSubviews {
  [super layoutSubviews];

  _inkView.frame = self.bounds;
  _imageView.frame = [self imageViewFrame];
  _selectedImageView.frame = [self selectedImageViewFrame];
  _accessoryView.frame = [self accessoryViewFrame];
  _titleLabel.frame = [self titleLabelFrame];

  _selectedImageView.alpha = self.showSelectedImageView ? 1 : 0;

  CGFloat cornerRadius = self.cornerRadius;
  if (self.shouldFullyRoundCorner) {
    CGRect visibleFrame = UIEdgeInsetsInsetRect(self.frame, self.visibleAreaInsets);
    cornerRadius = MIN(CGRectGetHeight(visibleFrame), CGRectGetWidth(visibleFrame)) / 2;
  }
  [self configureLayerWithCornerRadius:cornerRadius];

  // Handle RTL
  if (self.effectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
    for (UIView *subview in self.subviews) {
      CGRect flippedRect = MDFRectFlippedHorizontally(subview.frame, CGRectGetWidth(self.bounds));
      subview.frame = flippedRect;
    }
  }

  if (gEnablePerformantShadow && _shapedLayer.shapeGenerator) {
    [_shapedLayer layoutShapedSublayers];
  }

  [self updateBackgroundColor];
  [self updateBorderColor];
  [self updateShadowColor];
}

- (CGRect)contentRect {
  CGRect contentRect = UIEdgeInsetsInsetRect(self.bounds, self.visibleAreaInsets);
  contentRect = UIEdgeInsetsInsetRect(contentRect, self.contentPadding);
  UIControlContentHorizontalAlignment alignment = self.contentHorizontalAlignment;
  if (alignment != UIControlContentHorizontalAlignmentCenter) {
    return contentRect;
  }

  // Calculate the minimum width needed for all the content. If it's less than contentSize.width,
  // then inset to center. If not, just return contentRect.
  CGFloat neededContentWidth = 0;
  CGSize maxContentSize = contentRect.size;

  // If there's an imageView, add it and its padding.
  if (self.showImageView || self.showSelectedImageView) {
    CGFloat maxImageWidth = 0;
    if (self.showImageView) {
      maxImageWidth = [self sizeForImageView:self.imageView maxSize:maxContentSize].width;
    }
    if (self.showSelectedImageView) {
      maxImageWidth =
          MAX(maxImageWidth,
              [self sizeForImageView:self.selectedImageView maxSize:maxContentSize].width);
    }
    neededContentWidth += maxImageWidth + UIEdgeInsetsHorizontal(self.imagePadding);
  }

  // Always add the title and its padding.
  neededContentWidth += [_titleLabel sizeThatFits:maxContentSize].width;
  neededContentWidth += UIEdgeInsetsHorizontal(_titlePadding);

  // If there's an accessoryView, add it and its padding.
  if (self.showAccessoryView) {
    neededContentWidth += [self sizeForAccessoryViewWithMaxSize:maxContentSize].width;
    neededContentWidth += UIEdgeInsetsHorizontal(self.accessoryPadding);
  }

  CGFloat difference = maxContentSize.width - neededContentWidth;
  if (difference > 0) {
    CGFloat padding = difference / 2;
    contentRect.size.width -= difference;
    contentRect.origin.x += padding;
  }
  return contentRect;
}

- (CGRect)imageViewFrame {
  return [self frameForImageView:self.imageView visible:self.showImageView];
}

- (CGRect)selectedImageViewFrame {
  return [self frameForImageView:self.selectedImageView visible:self.showSelectedImageView];
}

- (CGRect)frameForImageView:(UIImageView *)imageView visible:(BOOL)visible {
  CGRect contentRect = self.contentRect;
  CGRect frame = CGRectMake(CGRectGetMinX(contentRect), CGRectGetMidY(contentRect), 0, 0);
  if (visible) {
    CGSize selectedSize = CGSizeEqualToSize(self.imageViewSize, CGSizeZero)
                              ? [self sizeForImageView:imageView maxSize:contentRect.size]
                              : self.imageViewSize;
    frame = MDCChipBuildFrame(_imagePadding, selectedSize,
                              CGPointMake(CGRectGetMinX(contentRect), CGRectGetMinY(contentRect)),
                              CGRectGetHeight(contentRect), self.pixelScale);
  }
  return frame;
}

- (CGSize)sizeForImageView:(UIImageView *)imageView maxSize:(CGSize)maxSize {
  CGSize availableSize = CGSizeShrinkWithInsets(maxSize, self.imagePadding);
  return [imageView sizeThatFits:availableSize];
}

- (CGRect)accessoryViewFrame {
  CGSize size = CGSizeZero;
  CGRect contentRect = self.contentRect;
  if (self.showAccessoryView) {
    size = [self sizeForAccessoryViewWithMaxSize:contentRect.size];
  }
  CGFloat xOffset =
      CGRectGetMaxX(self.contentRect) - size.width - UIEdgeInsetsHorizontal(_accessoryPadding);
  CGPoint frameOrigin = CGPointMake(xOffset, CGRectGetMinY(contentRect));
  return MDCChipBuildFrame(_accessoryPadding, size, frameOrigin, CGRectGetHeight(contentRect),
                           self.pixelScale);
}

- (CGSize)sizeForAccessoryViewWithMaxSize:(CGSize)maxSize {
  CGSize availableSize = CGSizeShrinkWithInsets(maxSize, self.accessoryPadding);
  return [_accessoryView sizeThatFits:availableSize];
}

- (CGRect)titleLabelFrame {
  // Default to the unselected image, but account for the selected image if it's shown.
  CGRect imageFrame = _imageView.frame;
  if (self.showSelectedImageView) {
    // Both images are present, take the union of their frames.
    if (self.showImageView) {
      imageFrame = CGRectUnion(_imageView.frame, _selectedImageView.frame);
    } else {
      imageFrame = _selectedImageView.frame;
    }
  }
  CGRect contentRect = self.contentRect;
  CGFloat maximumTitleWidth = CGRectGetWidth(contentRect) - CGRectGetWidth(imageFrame) -
                              UIEdgeInsetsHorizontal(_titlePadding);
  if (self.showImageView || self.showSelectedImageView) {
    maximumTitleWidth -= UIEdgeInsetsHorizontal(_imagePadding);
  }
  if (self.showAccessoryView) {
    maximumTitleWidth -=
        CGRectGetWidth(_accessoryView.frame) + UIEdgeInsetsHorizontal(_accessoryPadding);
  }
  CGFloat maximumTitleHeight = CGRectGetHeight(contentRect) - UIEdgeInsetsVertical(_titlePadding);
  CGSize maximumSize = CGSizeMake(maximumTitleWidth, maximumTitleHeight);
  CGSize titleSize = [_titleLabel sizeThatFits:maximumSize];
  titleSize.width = MAX(0, maximumTitleWidth);

  CGFloat imageRightEdge = CGRectGetMinX(contentRect);
  if (self.showImageView || self.showSelectedImageView) {
    imageRightEdge = CGRectGetMaxX(imageFrame) + _imagePadding.right;
  }
  CGPoint frameOrigin = CGPointMake(imageRightEdge, CGRectGetMinY(contentRect));
  return MDCChipBuildFrame(_titlePadding, titleSize, frameOrigin, CGRectGetHeight(contentRect),
                           self.pixelScale);
}

- (CGSize)sizeThatFits:(CGSize)size {
  CGSize contentPaddedSize = CGSizeShrinkWithInsets(size, self.contentPadding);
  CGSize imagePaddedSize = CGSizeShrinkWithInsets(contentPaddedSize, self.imagePadding);
  CGSize titlePaddedSize = CGSizeShrinkWithInsets(contentPaddedSize, self.titlePadding);
  CGSize accessoryPaddedSize = CGSizeShrinkWithInsets(contentPaddedSize, self.accessoryPadding);

  CGSize imageSize = CGSizeZero;
  CGSize selectedSize = CGSizeZero;

  if (self.showImageView) {
    imageSize =
        CGSizeExpandWithInsets([_imageView sizeThatFits:imagePaddedSize], self.imagePadding);
  }
  if (self.showSelectedImageView) {
    selectedSize = CGSizeExpandWithInsets([_selectedImageView sizeThatFits:imagePaddedSize],
                                          self.imagePadding);
  }
  imageSize.width = MAX(imageSize.width, selectedSize.width);
  imageSize.height = MAX(imageSize.height, selectedSize.height);

  CGSize originalTitleSize = [_titleLabel sizeThatFits:titlePaddedSize];
  CGSize titleSize = CGSizeExpandWithInsets(originalTitleSize, self.titlePadding);

  CGSize accessorySize = CGSizeZero;
  if (_accessoryView) {
    accessorySize = CGSizeExpandWithInsets([_accessoryView sizeThatFits:accessoryPaddedSize],
                                           self.accessoryPadding);
  }

  CGSize contentSize =
      CGSizeMake(imageSize.width + titleSize.width + accessorySize.width,
                 MAX(imageSize.height, MAX(titleSize.height, accessorySize.height)));
  CGSize chipSize = CGSizeExpandWithInsets(contentSize, self.contentPadding);
  if (self.minimumSize.width > 0) {
    chipSize.width = MAX(self.minimumSize.width, chipSize.width);
  }
  if (self.minimumSize.height > 0) {
    chipSize.height = MAX(self.minimumSize.height, chipSize.height);
  }
  return MDCSizeCeilWithScale(chipSize, self.pixelScale);
}

- (CGSize)intrinsicContentSize {
  return [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
}

- (void)willMoveToSuperview:(UIView *)newSuperview {
  [super willMoveToSuperview:newSuperview];
  [self.inkView cancelAllAnimationsAnimated:NO];
  [self.rippleView cancelAllRipplesAnimated:NO completion:nil];
}

- (BOOL)showImageView {
  return self.imageView.image != nil;
}

- (BOOL)showSelectedImageView {
  return self.selected && self.selectedImageView.image != nil;
}

- (BOOL)showAccessoryView {
  return self.accessoryView && !self.accessoryView.hidden;
}

- (CGFloat)pixelScale {
  return self.window.screen ? self.window.screen.scale : UIScreen.mainScreen.scale;
}

#pragma mark - Ink Touches

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  [super touchesBegan:touches withEvent:event];

  [self startTouchBeganAnimationAtPoint:[self locationFromTouches:touches]];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  [super touchesEnded:touches withEvent:event];

  [self startTouchEndedAnimationAtPoint:[self locationFromTouches:touches]];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
  [super touchesCancelled:touches withEvent:event];

  [self startTouchEndedAnimationAtPoint:[self locationFromTouches:touches]];
}

- (CGPoint)locationFromTouches:(NSSet *)touches {
  UITouch *touch = [touches anyObject];
  return [touch locationInView:self];
}

@end

@implementation MDCChipView (Private)

- (void)startTouchBeganAnimationAtPoint:(CGPoint)point {
  if (!self.enabled) {
    return;
  }

  if (self.disableInkAndRippleBehavior) {
    return;
  }

  CGSize size = [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
  CGFloat widthDiff = 24;  // Difference between unselected and selected frame widths.
  CGFloat maxRadius =
      (CGFloat)(hypot(size.height, size.width + widthDiff) / 2 + 10 + widthDiff / 2);
  if (self.enableRippleBehavior) {
    _rippleView.maximumRadius = maxRadius;
    [_rippleView beginRippleTouchDownAtPoint:point animated:YES completion:nil];
  } else {
    _inkView.maxRippleRadius = maxRadius;
    [_inkView startTouchBeganAnimationAtPoint:point completion:nil];
  }
}

- (void)startTouchEndedAnimationAtPoint:(CGPoint)point {
  if (self.disableInkAndRippleBehavior) {
    return;
  }

  if (self.enableRippleBehavior) {
    [_rippleView beginRippleTouchUpAnimated:YES completion:nil];
  } else {
    [_inkView startTouchEndedAnimationAtPoint:point completion:nil];
  }
}

- (BOOL)willChangeSizeWithSelectedValue:(BOOL)selected {
  if (selected == self.isSelected) {
    return NO;
  }
  BOOL hasImage = self.imageView.image != nil;
  BOOL hasSelectedImage = self.selectedImageView.image != nil;

  return !hasImage && hasSelectedImage;
}

#pragma mark - Performant Shadow Toggle

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

+ (BOOL)enablePerformantShadow {
  return gEnablePerformantShadow;
}

@end
