/*
 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 "MDCCollectionViewFlowLayout.h"

#import "MDCCollectionViewController.h"
#import "MDCCollectionViewEditingDelegate.h"
#import "MDCCollectionViewStyling.h"
#import "MaterialCollectionLayoutAttributes.h"
#import "private/MDCCollectionGridBackgroundView.h"
#import "private/MDCCollectionInfoBarView.h"
#import "private/MDCCollectionViewEditor.h"

#include <tgmath.h>

/** The grid background decoration view kind. */
NSString *const kCollectionGridDecorationView = @"MDCCollectionGridDecorationView";

static const NSInteger kSupplementaryViewZIndex = 99;

@implementation MDCCollectionViewFlowLayout {
  NSMutableArray<NSIndexPath *> *_deletedIndexPaths;
  NSMutableArray<NSIndexPath *> *_insertedIndexPaths;
  NSMutableIndexSet *_deletedSections;
  NSMutableIndexSet *_insertedSections;
  NSMutableIndexSet *_headerSections;
  NSMutableIndexSet *_footerSections;
  NSMutableDictionary *_decorationViewAttributeCache;
}

- (instancetype)init {
  self = [super init];
  if (self != nil) {
    [self commonMDCCollectionViewFlowLayoutInit];
  }
  return self;
}

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
  self = [super initWithCoder:aDecoder];
  if (self != nil) {
    // TODO(#): Use values from decoder, don't overwrite in commonInit
    [self commonMDCCollectionViewFlowLayoutInit];
  }
  return self;
}

- (void)commonMDCCollectionViewFlowLayoutInit {
  // Defaults.
  self.minimumLineSpacing = 0;
  self.minimumInteritemSpacing = 0;
  self.scrollDirection = UICollectionViewScrollDirectionVertical;
  self.sectionInset = UIEdgeInsetsZero;

  // Register decoration view for grid background.
  _decorationViewAttributeCache = [NSMutableDictionary dictionary];
  [self registerClass:[MDCCollectionGridBackgroundView class]
      forDecorationViewOfKind:kCollectionGridDecorationView];
}

- (id<MDCCollectionViewEditing>)editor {
  if ([self.collectionView.delegate isKindOfClass:[MDCCollectionViewController class]]) {
    MDCCollectionViewController *controller =
        (MDCCollectionViewController *)self.collectionView.delegate;
    return controller.editor;
  }
  return nil;
}

- (id<MDCCollectionViewStyling>)styler {
  if ([self.collectionView.delegate isKindOfClass:[MDCCollectionViewController class]]) {
    MDCCollectionViewController *controller =
        (MDCCollectionViewController *)self.collectionView.delegate;
    return controller.styler;
  }
  return nil;
}

#pragma mark - UICollectionViewLayout (SubclassingHooks)

- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:
        (CGRect)rect {
  // If performing appearance animation, increase bounds height in order to retrieve additional
  // offscreen attributes needed during animation.
  rect = [self boundsForAppearanceAnimationWithInitialBounds:rect];
  NSMutableArray<__kindof UICollectionViewLayoutAttributes *> *attributes =
      [[NSMutableArray alloc] initWithArray:[super layoutAttributesForElementsInRect:rect]
                                  copyItems:YES];

  // Store index path sections of any headers/footers within these attributes.
  [self storeSupplementaryViewsWithAttributes:attributes];

  // Set layout attributes.
  for (MDCCollectionViewLayoutAttributes *attr in attributes) {
    [self updateAttribute:attr];
  }

  // Add info bar header/footer supplementary view if necessary.
  [self addInfoBarAttributesIfNecessary:attributes];

  // Begin cell appearance animation if necessary.
  [self beginCellAppearanceAnimationIfNecessary:attributes];

  // Add a grid background decoration view for each section if necessary.
  [self addDecorationViewIfNecessary:attributes];

  return attributes;
}

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
  if (!CGSizeEqualToSize(self.collectionView.bounds.size, newBounds.size) ||
      self.editor.isEditing) {
    // Invalidate the layout to force cells to respect the new collection view bounds. Doing here
    // removes necessity to implement methods -willRotateToInterfaceOrientation:duration: and/or
    // -viewWillTransitionToSize:withTransitionCoordinator: on the collection view controller.
    [self invalidateLayout];
    return YES;
  }
  return NO;
}

- (void)invalidateLayout {
  [super invalidateLayout];

  // Clear decoration attribute cache.
  [_decorationViewAttributeCache removeAllObjects];
}

#pragma mark - UICollectionViewLayout (UISubclassingHooks)

+ (Class)layoutAttributesClass {
  return [MDCCollectionViewLayoutAttributes class];
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
  UICollectionViewLayoutAttributes *attr =
      [[super layoutAttributesForItemAtIndexPath:indexPath] copy];
  return [self updateAttribute:(MDCCollectionViewLayoutAttributes *)attr];
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind
                                                                     atIndexPath:
                                                                         (NSIndexPath *)indexPath {
  UICollectionViewLayoutAttributes *attr;

  if ([kind isEqualToString:UICollectionElementKindSectionHeader] ||
      [kind isEqualToString:UICollectionElementKindSectionFooter]) {
    // Update section headers/Footers attributes.
    attr = [[super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath] copy];
    if (!attr) {
      attr =
          [MDCCollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:kind
                                                                          withIndexPath:indexPath];
    }
    [self updateAttribute:(MDCCollectionViewLayoutAttributes *)attr];

  } else {
    // Update editing info bar attributes.
    attr = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:kind
                                                                          withIndexPath:indexPath];

    // Force the info bar supplementary views to stay fixed to their respective positions
    // at top/bottom of the collectionView bounds.
    CGFloat offsetY = 0;
    CGRect currentBounds = self.collectionView.bounds;
    attr.zIndex = kSupplementaryViewZIndex;

    if ([kind isEqualToString:MDCCollectionInfoBarKindHeader]) {
      attr.size = CGSizeMake(CGRectGetWidth(currentBounds), MDCCollectionInfoBarHeaderHeight);
      // Allow header to move upwards with scroll, but prevent from moving downwards with scroll.
      CGFloat insetTop = self.collectionView.contentInset.top;
#if defined(__IPHONE_11_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0)
      if (@available(iOS 11.0, *)) {
        insetTop = self.collectionView.adjustedContentInset.top;
      }
#endif
      CGFloat boundsY = currentBounds.origin.y;
      CGFloat maxOffsetY = MAX(boundsY + insetTop, 0);
      offsetY = boundsY + (attr.size.height / 2) + insetTop - maxOffsetY;
    } else if ([kind isEqualToString:MDCCollectionInfoBarKindFooter]) {
      CGFloat height = MDCCollectionInfoBarFooterHeight;
#if defined(__IPHONE_11_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0)
      if (@available(iOS 11.0, *)) {
        height += self.collectionView.safeAreaInsets.bottom;
      }
#endif
      attr.size = CGSizeMake(CGRectGetWidth(currentBounds), height);
      offsetY = currentBounds.origin.y + currentBounds.size.height - (attr.size.height / 2);
    }
    attr.center = CGPointMake(CGRectGetMidX(currentBounds), offsetY);
  }
  return attr;
}

- (UICollectionViewLayoutAttributes *)
    layoutAttributesForDecorationViewOfKind:(NSString *)elementKind
                                atIndexPath:(NSIndexPath *)indexPath {
  // Check cache for decoration view attributes, and add to cache if they don't exist.
  MDCCollectionViewLayoutAttributes *decorationAttr =
      [_decorationViewAttributeCache objectForKey:indexPath];
  if (!decorationAttr) {
    decorationAttr =
        [MDCCollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:elementKind
                                                                     withIndexPath:indexPath];
    [_decorationViewAttributeCache setObject:decorationAttr forKey:indexPath];
  }

  // Determine section frame by summing all of its item frames.
  CGRect sectionFrame = CGRectNull;
  for (NSInteger i = 0; i < [self numberOfItemsInSection:indexPath.section]; ++i) {
    indexPath = [NSIndexPath indexPathForItem:i inSection:indexPath.section];
    UICollectionViewLayoutAttributes *attribute =
        [self layoutAttributesForItemAtIndexPath:indexPath];
    if (!CGRectIsNull(attribute.frame)) {
      sectionFrame = CGRectUnion(sectionFrame, attribute.frame);
    }
  }
  if (!CGRectIsNull(sectionFrame)) {
    decorationAttr.frame = sectionFrame;
  }

  decorationAttr.zIndex = -1;
  return decorationAttr;
}

- (CGPoint)targetContentOffsetForProposedContentOffset:(__unused CGPoint)proposedContentOffset {
  // Return current contentOffset to prevent any layout animations from jumping to new offset.
  return [super targetContentOffsetForProposedContentOffset:self.collectionView.contentOffset];
}

#pragma mark - UICollectionViewLayout (UIUpdateSupportHooks)

- (void)prepareForCollectionViewUpdates:(NSArray<UICollectionViewUpdateItem *> *)updateItems {
  [super prepareForCollectionViewUpdates:updateItems];
  _deletedIndexPaths = [NSMutableArray array];
  _insertedIndexPaths = [NSMutableArray array];
  _deletedSections = [NSMutableIndexSet indexSet];
  _insertedSections = [NSMutableIndexSet indexSet];

  for (UICollectionViewUpdateItem *item in updateItems) {
    if (item.updateAction == UICollectionUpdateActionDelete) {
      // Store deleted sections or indexPaths.
      if (item.indexPathBeforeUpdate.item == NSNotFound) {
        [_deletedSections addIndex:item.indexPathBeforeUpdate.section];
      } else {
        [_deletedIndexPaths addObject:item.indexPathBeforeUpdate];
      }

    } else if (item.updateAction == UICollectionUpdateActionInsert) {
      // Store inserted sections or indexPaths.
      if (item.indexPathAfterUpdate.item == NSNotFound) {
        [_insertedSections addIndex:item.indexPathAfterUpdate.section];
      } else {
        [_insertedIndexPaths addObject:item.indexPathAfterUpdate];
      }
    }
  }
}

- (void)finalizeCollectionViewUpdates {
  [super finalizeCollectionViewUpdates];
  _deletedIndexPaths = nil;
  _insertedIndexPaths = nil;
  _deletedSections = nil;
  _insertedSections = nil;
}

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:
        (NSIndexPath *)itemIndexPath {
  UICollectionViewLayoutAttributes *attr =
      [[super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath] copy];
  // Adding new section or item.
  if ([_insertedSections containsIndex:itemIndexPath.section] ||
      [_insertedIndexPaths containsObject:itemIndexPath]) {
    attr.transform = CGAffineTransformMakeTranslation(0, -CGRectGetHeight(attr.bounds) / 2);
  } else {
    attr.alpha = 1;
  }
  return attr;
}

- (UICollectionViewLayoutAttributes *)
    initialLayoutAttributesForAppearingSupplementaryElementOfKind:(NSString *)elementKind
                                                      atIndexPath:(NSIndexPath *)elementIndexPath {
  UICollectionViewLayoutAttributes *attr =
      [[super initialLayoutAttributesForAppearingSupplementaryElementOfKind:elementKind
                                                                atIndexPath:elementIndexPath] copy];
  if ([elementKind isEqualToString:UICollectionElementKindSectionHeader] ||
      [elementKind isEqualToString:UICollectionElementKindSectionFooter]) {
    // Adding new section header or footer.
    if ([_insertedSections containsIndex:elementIndexPath.section]) {
      attr.transform = CGAffineTransformMakeTranslation(0, -CGRectGetHeight(attr.bounds) / 2);
    } else {
      attr.alpha = 1;
    }
  }
  return attr;
}

- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:
        (NSIndexPath *)itemIndexPath {
  UICollectionViewLayoutAttributes *attr =
      [[super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath] copy];
  // Deleting section or item.
  if ([_deletedSections containsIndex:itemIndexPath.section] ||
      [_deletedIndexPaths containsObject:itemIndexPath]) {
    attr.transform = CGAffineTransformMakeTranslation(0, -CGRectGetHeight(attr.bounds) / 2);
  } else {
    attr.alpha = 1;
  }
  return attr;
}

- (UICollectionViewLayoutAttributes *)
    finalLayoutAttributesForDisappearingSupplementaryElementOfKind:(NSString *)elementKind
                                                       atIndexPath:(NSIndexPath *)elementIndexPath {
  UICollectionViewLayoutAttributes *attr = [[super
      finalLayoutAttributesForDisappearingSupplementaryElementOfKind:elementKind
                                                         atIndexPath:elementIndexPath] copy];
  if ([elementKind isEqualToString:UICollectionElementKindSectionHeader] ||
      [elementKind isEqualToString:UICollectionElementKindSectionFooter]) {
    // Deleting section header or footer.
    if ([_deletedSections containsIndex:elementIndexPath.section]) {
      attr.transform = CGAffineTransformMakeTranslation(0, -CGRectGetHeight(attr.bounds) / 2);
    } else {
      attr.alpha = 1;
    }
  }
  return attr;
}

#pragma mark - Header/Footer Caching

- (void)storeSupplementaryViewsWithAttributes:
        (NSArray<__kindof UICollectionViewLayoutAttributes *> *)attributes {
  _headerSections = [NSMutableIndexSet indexSet];
  _footerSections = [NSMutableIndexSet indexSet];

  // Store index path sections for headers/footers.
  for (MDCCollectionViewLayoutAttributes *attr in attributes) {
    if ([attr.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
      [_headerSections addIndex:attr.indexPath.section];
    } else if ([attr.representedElementKind isEqualToString:UICollectionElementKindSectionFooter]) {
      [_footerSections addIndex:attr.indexPath.section];
    }
  }
}

#pragma mark - Private

- (MDCCollectionViewLayoutAttributes *)updateAttribute:(MDCCollectionViewLayoutAttributes *)attr {
  if (attr.representedElementCategory == UICollectionElementCategoryCell) {
    attr.editing = self.editor.isEditing;
  }
  attr.isGridLayout = NO;
  if (self.styler.cellLayoutType == MDCCollectionViewCellLayoutTypeList) {
    attr.sectionOrdinalPosition = [self ordinalPositionForListElementWithAttribute:attr];
  } else if (self.styler.cellLayoutType == MDCCollectionViewCellLayoutTypeGrid) {
    attr.sectionOrdinalPosition = [self ordinalPositionForGridElementWithAttribute:attr];
    attr.isGridLayout = YES;
  }

  [self updateCellStateMaskWithAttribute:attr];

  if (attr.representedElementCategory == UICollectionElementCategorySupplementaryView) {
    attr = [self updateSupplementaryViewAttribute:attr];
  }

  // Set cell background.
  attr.backgroundImage = [self.styler backgroundImageForCellLayoutAttributes:attr];
  attr.backgroundImageViewInsets =
      [self.styler backgroundImageViewOutsetsForCellWithAttribute:attr];

  // Set separator styling.
  attr.separatorColor = self.styler.separatorColor;
  attr.separatorInset = self.styler.separatorInset;
  attr.separatorLineHeight = self.styler.separatorLineHeight;
  attr.shouldHideSeparators = [self.styler shouldHideSeparatorForCellLayoutAttributes:attr];

  // Set inlay and hidden state if necessary.
  [self inlayAttributeIfNecessary:attr];
  [self hideAttributeIfNecessary:attr];

  return attr;
}

- (MDCCollectionViewLayoutAttributes *)updateSupplementaryViewAttribute:
        (MDCCollectionViewLayoutAttributes *)attr {
  // In vertical scrolling, supplementary views only respect their height and ignore their width
  // value. The opposite is true for horizontal scrolling. Therefore we must manually set insets
  // on both the backgroundView and contentView in order to match the insets of the collection
  // view rows.
  CGRect insetFrame = attr.frame;
  if (!CGRectIsEmpty(insetFrame)) {
    UIEdgeInsets insets;

    // Retrieve the insets from the Flow Layout delegate to maintain consistency with the CVC
    if ([self.collectionView.delegate
            respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
      id<UICollectionViewDelegateFlowLayout> flowLayoutDelegate =
          (id<UICollectionViewDelegateFlowLayout>)self.collectionView.delegate;
      insets = [flowLayoutDelegate collectionView:self.collectionView
                                           layout:self.collectionView.collectionViewLayout
                           insetForSectionAtIndex:attr.indexPath.section];
    } else {
      insets = [self insetsAtSectionIndex:attr.indexPath.section];
    }

    if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
      insetFrame = CGRectInset(insetFrame, insets.left / 2 + insets.right / 2, 0);
      if ([attr.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
        insetFrame.origin.y += insets.top;
      } else if ([attr.representedElementKind
                     isEqualToString:UICollectionElementKindSectionFooter]) {
        insetFrame.origin.y -= insets.bottom;
      }
      attr.frame = insetFrame;
    }
  }
  return attr;
}

- (UIEdgeInsets)insetsAtSectionIndex:(NSInteger)section {
  // Determine insets based on cell style.
  CGFloat inset = (CGFloat)floor(MDCCollectionViewCellStyleCardSectionInset);
  UIEdgeInsets insets = UIEdgeInsetsZero;
  NSInteger numberOfSections = self.collectionView.numberOfSections;
  BOOL isTop = (section == 0);
  BOOL isBottom = (section == numberOfSections - 1);
  MDCCollectionViewCellStyle cellStyle = [self.styler cellStyleAtSectionIndex:section];
  BOOL isCardStyle = cellStyle == MDCCollectionViewCellStyleCard;
  BOOL isGroupedStyle = cellStyle == MDCCollectionViewCellStyleGrouped;
  // Set left/right insets.
  if (isCardStyle) {
    insets.left = inset;
    insets.right = inset;
  }
  // Set top/bottom insets.
  if (isCardStyle || isGroupedStyle) {
    insets.top = (CGFloat)floor((isTop) ? inset : inset / 2.0f);
    insets.bottom = (CGFloat)floor((isBottom) ? inset : inset / 2.0f);
  }
  return insets;
}

- (MDCCollectionViewOrdinalPosition)ordinalPositionForListElementWithAttribute:
        (MDCCollectionViewLayoutAttributes *)attr {
  // Returns the ordinal position of cells and supplementary views within a list layout. This is
  // used to determine the layout attributes applied to their styling.
  MDCCollectionViewOrdinalPosition position = 0;
  NSIndexPath *indexPath = attr.indexPath;
  NSInteger numberOfItemsInSection = [self numberOfItemsInSection:indexPath.section];
  BOOL isTop = NO;
  BOOL isBottom = NO;
  BOOL hasSectionHeader = [_headerSections containsIndex:indexPath.section];
  BOOL hasSectionFooter = [_footerSections containsIndex:indexPath.section];
  BOOL hasSectionItems = [self numberOfItemsInSection:indexPath.section] > 0;

  BOOL hidesHeaderBackground = NO;
  if ([self.styler.delegate
          respondsToSelector:@selector(collectionView:shouldHideHeaderBackgroundForSection:)]) {
    hidesHeaderBackground = [self.styler.delegate collectionView:self.styler.collectionView
                            shouldHideHeaderBackgroundForSection:indexPath.section];
  }

  BOOL hidesFooterBackground = NO;
  if ([self.styler.delegate
          respondsToSelector:@selector(collectionView:shouldHideFooterBackgroundForSection:)]) {
    hidesFooterBackground = [self.styler.delegate collectionView:self.styler.collectionView
                            shouldHideFooterBackgroundForSection:indexPath.section];
  }

  if (attr.representedElementCategory == UICollectionElementCategoryCell) {
    isTop = (indexPath.item == 0) && (!hasSectionHeader || hidesHeaderBackground);
    isBottom = (indexPath.item == numberOfItemsInSection - 1) &&
               (!hasSectionFooter || hidesFooterBackground);
  } else if (attr.representedElementCategory == UICollectionElementCategorySupplementaryView) {
    NSString *kind = attr.representedElementKind;
    BOOL isElementHeader = ([kind isEqualToString:UICollectionElementKindSectionHeader]);
    BOOL isElementFooter = ([kind isEqualToString:UICollectionElementKindSectionFooter]);
    isTop = (isElementFooter && !hasSectionItems && !hasSectionHeader) || isElementHeader;
    isBottom = (isElementHeader && !hasSectionItems && !hasSectionFooter) || isElementFooter;
  }

  if (attr.editing || [self.styler isItemInlaidAtIndexPath:attr.indexPath]) {
    isTop = YES;
    isBottom = YES;
  }

  if (!isTop && !isBottom) {
    position |= MDCCollectionViewOrdinalPositionVerticalCenter;
  } else {
    position |= isTop ? MDCCollectionViewOrdinalPositionVerticalTop : position;
    position |= isBottom ? MDCCollectionViewOrdinalPositionVerticalBottom : position;
  }
  return position;
}

- (MDCCollectionViewOrdinalPosition)ordinalPositionForGridElementWithAttribute:
        (MDCCollectionViewLayoutAttributes *)attr {
  // Returns the ordinal position of cells and supplementary views within a grid layout. This is
  // used to determine the layout attributes applied to their styling.
  MDCCollectionViewOrdinalPosition position = 0;
  NSIndexPath *indexPath = attr.indexPath;
  NSInteger numberOfItemsInSection = [self numberOfItemsInSection:indexPath.section];
  NSInteger gridColumnCount = self.styler.gridColumnCount;
  NSInteger maxRowIndex = (NSInteger)(floor(numberOfItemsInSection / gridColumnCount) - 1);
  NSInteger maxColumnIndex = gridColumnCount - 1;
  NSInteger ordinalRow = (NSInteger)(floor(indexPath.item / gridColumnCount));
  NSInteger ordinalColumn = (NSInteger)(floor(indexPath.item % gridColumnCount));

  // Set vertical ordinal position.
  if (ordinalRow > 0 && ordinalRow < maxRowIndex) {
    position = position | MDCCollectionViewOrdinalPositionVerticalCenter;
  } else {
    position =
        (ordinalRow == 0) ? position | MDCCollectionViewOrdinalPositionVerticalTop : position;
    position = (ordinalRow == maxRowIndex)
                   ? position | MDCCollectionViewOrdinalPositionVerticalBottom
                   : position;
  }

  // Set horizontal ordinal position.
  if (ordinalColumn > 0 && ordinalColumn < maxColumnIndex) {
    position = position | MDCCollectionViewOrdinalPositionHorizontalCenter;
  } else {
    position =
        (ordinalColumn == 0) ? position | MDCCollectionViewOrdinalPositionHorizontalLeft : position;
    position = (ordinalColumn == maxColumnIndex)
                   ? position | MDCCollectionViewOrdinalPositionHorizontalRight
                   : position;
  }
  return position;
}

- (void)updateCellStateMaskWithAttribute:(MDCCollectionViewLayoutAttributes *)attr {
  attr.shouldShowSelectorStateMask = NO;
  attr.shouldShowReorderStateMask = NO;

  // Determine proper state to show cell if editing.
  if (attr.editing) {
    if ([self.collectionView.dataSource
            conformsToProtocol:@protocol(MDCCollectionViewEditingDelegate)]) {
      id<MDCCollectionViewEditingDelegate> editingDelegate =
          (id<MDCCollectionViewEditingDelegate>)self.collectionView.dataSource;

      // Check if delegate can select during editing.
      if ([editingDelegate respondsToSelector:@selector
                           (collectionView:canSelectItemDuringEditingAtIndexPath:)]) {
        attr.shouldShowSelectorStateMask = [editingDelegate collectionView:self.collectionView
                                     canSelectItemDuringEditingAtIndexPath:attr.indexPath];
      }

      // Check if delegate can reorder.
      if ([editingDelegate respondsToSelector:@selector(collectionView:canMoveItemAtIndexPath:)]) {
        attr.shouldShowReorderStateMask = [editingDelegate collectionView:self.collectionView
                                                   canMoveItemAtIndexPath:attr.indexPath];
      }
    }
  }
}

- (void)inlayAttributeIfNecessary:(MDCCollectionViewLayoutAttributes *)attr {
  // Inlay this attribute if necessary.
  CGFloat inset = MDCCollectionViewCellStyleCardSectionInset;
  UIEdgeInsets inlayInsets = UIEdgeInsetsZero;
  NSInteger item = attr.indexPath.item;
  NSArray<NSIndexPath *> *inlaidIndexPaths = [self.styler indexPathsForInlaidItems];

  // Update ordinal position for index paths adjacent to inlaid index path.
  for (NSIndexPath *inlaidIndexPath in inlaidIndexPaths) {
    if (inlaidIndexPath.section == attr.indexPath.section) {
      NSInteger numberOfItemsInSection = [self numberOfItemsInSection:inlaidIndexPath.section];
      if (attr.representedElementCategory == UICollectionElementCategoryCell) {
        if (item == inlaidIndexPath.item) {
          // Get previous and next index paths to the inlaid index path.
          BOOL prevAttrIsInlaid = NO;
          BOOL nextAttrIsInlaid = NO;
          BOOL hasSectionHeader = [_headerSections containsIndex:inlaidIndexPath.section];
          BOOL hasSectionFooter = [_footerSections containsIndex:inlaidIndexPath.section];

          if (inlaidIndexPath.item > 0 || hasSectionHeader) {
            NSIndexPath *prevIndexPath = [NSIndexPath indexPathForItem:(inlaidIndexPath.item - 1)
                                                             inSection:inlaidIndexPath.section];
            prevAttrIsInlaid = [self.styler isItemInlaidAtIndexPath:prevIndexPath];
            inlayInsets.top = prevAttrIsInlaid ? inset / 2 : inset;
          }

          if (inlaidIndexPath.item < numberOfItemsInSection - 1 || hasSectionFooter) {
            NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:(inlaidIndexPath.item + 1)
                                                             inSection:inlaidIndexPath.section];
            nextAttrIsInlaid = [self.styler isItemInlaidAtIndexPath:nextIndexPath];
            inlayInsets.bottom = nextAttrIsInlaid ? inset / 2 : inset;
          }

          // Is attribute to be inlaid.
          attr.frame = UIEdgeInsetsInsetRect(attr.frame, inlayInsets);
          attr.sectionOrdinalPosition = MDCCollectionViewOrdinalPositionVerticalTopBottom;
        } else if (item == inlaidIndexPath.item - 1) {
          // Is previous to inlaid attribute.
          if (attr.sectionOrdinalPosition & MDCCollectionViewOrdinalPositionVerticalTop) {
            attr.sectionOrdinalPosition = MDCCollectionViewOrdinalPositionVerticalTopBottom;
          } else if (attr.sectionOrdinalPosition & MDCCollectionViewOrdinalPositionVerticalCenter) {
            attr.sectionOrdinalPosition = MDCCollectionViewOrdinalPositionVerticalBottom;
          }
        } else if (item == inlaidIndexPath.item + 1) {
          // Is next to inlaid attribute.
          if (attr.sectionOrdinalPosition & MDCCollectionViewOrdinalPositionVerticalCenter) {
            attr.sectionOrdinalPosition = MDCCollectionViewOrdinalPositionVerticalTop;
          } else if (attr.sectionOrdinalPosition & MDCCollectionViewOrdinalPositionVerticalBottom) {
            attr.sectionOrdinalPosition = MDCCollectionViewOrdinalPositionVerticalBottom;
          }
        }

      } else if (attr.representedElementCategory == UICollectionElementCategorySupplementaryView) {
        // If header/footer attribute, update if adjacent to inlaid index path.
        NSString *kind = attr.representedElementKind;
        BOOL isElementHeader = ([kind isEqualToString:UICollectionElementKindSectionHeader]);
        BOOL isElementFooter = ([kind isEqualToString:UICollectionElementKindSectionFooter]);
        if (isElementHeader && inlaidIndexPath.item == 0) {
          attr.sectionOrdinalPosition = MDCCollectionViewOrdinalPositionVerticalTopBottom;
        } else if (isElementFooter && inlaidIndexPath.item == numberOfItemsInSection - 1) {
          attr.sectionOrdinalPosition = MDCCollectionViewOrdinalPositionVerticalTopBottom;
        }
      }
    }
  }
}

- (void)hideAttributeIfNecessary:(MDCCollectionViewLayoutAttributes *)attr {
  if (self.editor) {
    // Hide the attribute if the editor is either currently handling a cell item or section swipe
    // for dismissal, or is reordering a cell item.
    BOOL isCell = attr.representedElementCategory == UICollectionElementCategoryCell;
    if (attr.indexPath.section == self.editor.dismissingSection ||
        ([attr.indexPath isEqual:self.editor.dismissingCellIndexPath] && isCell) ||
        ([attr.indexPath isEqual:self.editor.reorderingCellIndexPath] && isCell)) {
      attr.hidden = YES;
    }
  }
}

- (void)addInfoBarAttributesIfNecessary:
        (NSMutableArray<__kindof UICollectionViewLayoutAttributes *> *)attributes {
  if (self.editor.isEditing && [attributes count] > 0) {
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];

    // Add header info bar if editing.
    [attributes
        addObject:[self layoutAttributesForSupplementaryViewOfKind:MDCCollectionInfoBarKindHeader
                                                       atIndexPath:indexPath]];

    // Add footer info bar if editing and item(s) are selected.
    NSInteger selectedItemCount = [self.collectionView.indexPathsForSelectedItems count];
    if (selectedItemCount > 0) {
      [attributes
          addObject:[self layoutAttributesForSupplementaryViewOfKind:MDCCollectionInfoBarKindFooter
                                                         atIndexPath:indexPath]];
    }
  }
}

- (void)addDecorationViewIfNecessary:
        (NSMutableArray<__kindof UICollectionViewLayoutAttributes *> *)attributes {
  // If necessary, adds a decoration view to a section drawn below its items. This will only happen
  // for a grid layout when it is either A) grouped-style or B) card-style with zero padding. When
  // this happens, the background for those items will not be drawn, and instead this decoration
  // view will extend to the bounds of the sum of its respective section item frames. Shadowing and
  // border will be applied to this decoration view as per the styler settings.
  if (self.styler.cellLayoutType == MDCCollectionViewCellLayoutTypeGrid) {
    NSMutableSet *sectionSet = [NSMutableSet set];
    BOOL shouldShowGridBackground = NO;
    NSMutableArray<__kindof UICollectionViewLayoutAttributes *> *decorationAttributes =
        [NSMutableArray array];
    for (MDCCollectionViewLayoutAttributes *attr in attributes) {
      NSInteger section = attr.indexPath.section;

      // Only add one decoration view per section.
      if (![sectionSet containsObject:@(section)]) {
        NSIndexPath *decorationIndexPath = [NSIndexPath indexPathForItem:0 inSection:section];
        MDCCollectionViewLayoutAttributes *decorationAttr =
            (MDCCollectionViewLayoutAttributes *)[self
                layoutAttributesForDecorationViewOfKind:kCollectionGridDecorationView
                                            atIndexPath:decorationIndexPath];
        shouldShowGridBackground = [self shouldShowGridBackgroundWithAttribute:decorationAttr];
        decorationAttr.shouldShowGridBackground = shouldShowGridBackground;
        decorationAttr.backgroundImage =
            shouldShowGridBackground
                ? [self.styler backgroundImageForCellLayoutAttributes:decorationAttr]
                : nil;
        [decorationAttributes addObject:decorationAttr];
        [sectionSet addObject:@(section)];
      }
      if (shouldShowGridBackground) {
        attr.backgroundImage = nil;
      }
    }
    [attributes addObjectsFromArray:decorationAttributes];
  }
}

- (BOOL)shouldShowGridBackgroundWithAttribute:(__unused MDCCollectionViewLayoutAttributes *)attr {
  // Determine whether to show grid background.
  if (self.styler.cellLayoutType == MDCCollectionViewCellLayoutTypeGrid) {
    if (self.styler.cellStyle == MDCCollectionViewCellStyleGrouped ||
        (self.styler.cellStyle == MDCCollectionViewCellStyleCard && self.styler.gridPadding == 0)) {
      return YES;
    }
  }
  return NO;
}

- (NSInteger)numberOfItemsInSection:(NSInteger)section {
  return [self.collectionView numberOfItemsInSection:section];
}

#pragma mark - Cell Appearance Animation

- (CGRect)boundsForAppearanceAnimationWithInitialBounds:(CGRect)initialBounds {
  // Increase initial bounds by 25% allowing offscreen attributes to be included in the
  // appearance animation.
  if (self.styler.shouldAnimateCellsOnAppearance && self.styler.willAnimateCellsOnAppearance) {
    CGRect newBounds = initialBounds;
    newBounds.size.height += (newBounds.size.height / 4);
    return newBounds;
  }
  return initialBounds;
}

- (void)beginCellAppearanceAnimationIfNecessary:
        (NSMutableArray<__kindof UICollectionViewLayoutAttributes *> *)attributes {
  // Here we want to assign a delay to each attribute such that the animation will fade-in from the
  // top downwards in a staggered manner. However, the array of attributes we receive here are not
  // in the correct order and must be sorted and re-ordered to properly assign these delays.
  //
  // First we will sort the array of attributes by index path to ensure proper ordering. Secondly
  // we will manipulate the array to bring any headers before their first respective cell items.
  //
  // When completed, we will end up with an array of attributes in the form of
  // header -> item -> footer ... repeated for each section. Now we can use this ordered array
  // to assign delays based on their proper ordinal position from top down.
  __block NSInteger attributeCount = attributes.count;
  NSTimeInterval duration = self.styler.animateCellsOnAppearanceDuration;
  if (self.styler.shouldAnimateCellsOnAppearance && attributeCount > 0) {
    // First sort by index path.
    NSArray<__kindof UICollectionViewLayoutAttributes *> *sortedByIndexPath = [attributes
        sortedArrayUsingComparator:^NSComparisonResult(MDCCollectionViewLayoutAttributes *attr1,
                                                       MDCCollectionViewLayoutAttributes *attr2) {
          return [attr1.indexPath compare:attr2.indexPath];
        }];

    // Next create new array containing attributes in the form of header -> item -> footer.
    NSMutableArray<__kindof UICollectionViewLayoutAttributes *> *sortedAttributes =
        [NSMutableArray array];
    [sortedByIndexPath enumerateObjectsUsingBlock:^(MDCCollectionViewLayoutAttributes *attr,
                                                    __unused NSUInteger idx, __unused BOOL *stop) {
      if (sortedAttributes.count > 0) {
        // Check if current attribute is a header and previous attribute is an item. If so,
        // insert the current header attribute before the cell.
        MDCCollectionViewLayoutAttributes *prevAttr =
            [sortedAttributes objectAtIndex:sortedAttributes.count - 1];
        BOOL prevAttrIsItem =
            prevAttr.representedElementCategory == UICollectionElementCategoryCell;
        BOOL attrIsHeader =
            [attr.representedElementKind isEqualToString:UICollectionElementKindSectionHeader];
        if (attrIsHeader && prevAttrIsItem) {
          [sortedAttributes insertObject:attr atIndex:sortedAttributes.count - 1];
          return;
        }
        if ([attr.representedElementKind isEqualToString:MDCCollectionInfoBarKindHeader] ||
            [attr.representedElementKind isEqualToString:MDCCollectionInfoBarKindFooter]) {
          // Reduce the attributeCount here to reflect only attributes that can be animated.
          attributeCount--;
          return;
        }
      }
      [sortedAttributes addObject:attr];
    }];

    // Now assign delays and add padding to frame Y coordinate which gets removed during animation.
    [sortedAttributes enumerateObjectsUsingBlock:^(MDCCollectionViewLayoutAttributes *attr,
                                                   NSUInteger idx, __unused BOOL *stop) {
      // If the element is an info bar header, then don't do anything.
      attr.willAnimateCellsOnAppearance = self.styler.willAnimateCellsOnAppearance;
      attr.animateCellsOnAppearanceDuration = self.styler.animateCellsOnAppearanceDuration;
      attr.animateCellsOnAppearanceDelay =
          (attributeCount > 0) ? ((CGFloat)idx / attributeCount) * duration : 0;

      if (self.styler.willAnimateCellsOnAppearance) {
        CGRect frame = attr.frame;
        frame.origin.y += self.styler.animateCellsOnAppearancePadding;
        attr.frame = frame;
      }
    }];

    // Call asynchronously to allow the current layout cycle to complete before issuing animations.
    if (self.styler.willAnimateCellsOnAppearance) {
      dispatch_async(dispatch_get_main_queue(), ^{
        [self.styler beginCellAppearanceAnimation];
      });
    }
  }
}

@end
