// 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 "private/MDCCollectionGridBackgroundView.h"
#import "private/MDCCollectionInfoBarView.h"
#import "MDCCollectionViewLayoutAttributes.h"
#import "MDCCollectionViewController.h"
#import "MDCCollectionViewEditing.h"
#import "MDCCollectionViewEditingDelegate.h"
#import "MDCCollectionViewStyling.h"
#import "MDCCollectionViewStylingDelegate.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;
      insetTop = self.collectionView.adjustedContentInset.top;
      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;
      height += self.collectionView.safeAreaInsets.bottom;
      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);
    insets.bottom = (CGFloat)floor((isBottom) ? inset : inset / 2);
  }
  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
