// Copyright 2018-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 "MDCBottomDrawerViewController.h"

#import "private/MDCBottomDrawerHeaderMask.h"
#import "MDCBottomDrawerTransitionController.h"
#import "MDCBottomDrawerViewControllerDelegate.h"
#import "MaterialMath.h"
#import "MaterialUIMetrics.h"

@interface MDCBottomDrawerViewController () <MDCBottomDrawerPresentationControllerDelegate>

/** The transition controller. */
@property(nonatomic) MDCBottomDrawerTransitionController *transitionController;
@property(nonatomic) MDCBottomDrawerHeaderMask *maskLayer;

@end

@implementation MDCBottomDrawerViewController {
  NSMutableDictionary<NSNumber *, NSNumber *> *_topCornersRadius;
  BOOL _isMaskAppliedFirstTime;

  // Used for forwarding touch events if enabled.
  __weak UIResponder *_cachedNextResponder;
  // Used for tracking the presentation/dismissal animations.
  BOOL _isDrawerClosed;
  CGFloat _lastOffset;
}

@synthesize mdc_overrideBaseElevation = _mdc_overrideBaseElevation;
@synthesize mdc_elevationDidChangeBlock = _mdc_elevationDidChangeBlock;

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
  self = [super initWithNibName:nil bundle:nil];
  if (self) {
    [self commonMDCBottomDrawerViewControllerInit];
  }
  return self;
}

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

- (void)commonMDCBottomDrawerViewControllerInit {
  _transitionController = [[MDCBottomDrawerTransitionController alloc] init];
  _topCornersRadius = [NSMutableDictionary dictionary];
  _topCornersRadius[@(MDCBottomDrawerStateCollapsed)] = @(0);
  _maskLayer = [[MDCBottomDrawerHeaderMask alloc] initWithMaximumCornerRadius:0
                                                          minimumCornerRadius:0];
  _maximumInitialDrawerHeight = 0;
  _maximumDrawerHeight = 0;
  _drawerShadowColor = [UIColor.blackColor colorWithAlphaComponent:(CGFloat)0.2];
  _elevation = MDCShadowElevationNavDrawer;
  _mdc_overrideBaseElevation = -1;

  _dismissOnBackgroundTap = YES;
  _shouldDismissOnAccessibilityPerformEscape = YES;
  _shouldForwardBackgroundTouchEvents = NO;
  _shouldDisplayMobileLandscapeFullscreen = YES;
  _isDrawerClosed = YES;
  _lastOffset = NSNotFound;
}

- (void)viewWillLayoutSubviews {
  [super viewWillLayoutSubviews];
  if (!_isMaskAppliedFirstTime) {
    _maskLayer.minimumCornerRadius = [self minimumCornerRadius];
    [_maskLayer applyMask];
    _isMaskAppliedFirstTime = YES;
  }
}

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

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

- (id<UIViewControllerTransitioningDelegate>)transitioningDelegate {
  return self.transitionController;
}

- (UIModalPresentationStyle)modalPresentationStyle {
  return UIModalPresentationCustom;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
  return self.presentingViewController.supportedInterfaceOrientations;
}

- (void)setTrackingScrollView:(UIScrollView *)trackingScrollView {
  _trackingScrollView = trackingScrollView;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.trackingScrollView = trackingScrollView;
  }
  // Rather than have the client manually disable scrolling on the internal scroll view for
  // the drawer to work properly, we can disable it if a trackingScrollView is provided.
  [trackingScrollView setScrollEnabled:NO];
}

- (void)setTopCornersRadius:(CGFloat)radius forDrawerState:(MDCBottomDrawerState)drawerState {
  _topCornersRadius[@(drawerState)] = @(radius);

  if (drawerState == MDCBottomDrawerStateCollapsed) {
    _maskLayer.maximumCornerRadius = radius;
  } else {
    _maskLayer.minimumCornerRadius = [self minimumCornerRadius];
  }
}

- (CGFloat)minimumCornerRadius {
  return [self contentReachesFullScreen]
             ? [self topCornersRadiusForDrawerState:MDCBottomDrawerStateFullScreen]
             : [self topCornersRadiusForDrawerState:MDCBottomDrawerStateExpanded];
}

- (CGFloat)topCornersRadiusForDrawerState:(MDCBottomDrawerState)drawerState {
  NSNumber *topCornersRadius = _topCornersRadius[@(drawerState)];
  if (topCornersRadius != nil) {
    return (CGFloat)[topCornersRadius doubleValue];
  }
  return 0;
}

- (void)setHeaderViewController:(UIViewController<MDCBottomDrawerHeader> *)headerViewController {
  _headerViewController = headerViewController;
  _maskLayer.view = headerViewController.view;
}

- (void)setContentViewController:(UIViewController *)contentViewController {
  _contentViewController = contentViewController;
  if (!_headerViewController) {
    _maskLayer.view = contentViewController.view;
  }
}

- (void)setScrimColor:(UIColor *)scrimColor {
  _scrimColor = scrimColor;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.scrimColor = scrimColor;
  }
}

- (BOOL)isAccessibilityMode {
  return UIAccessibilityIsVoiceOverRunning() || UIAccessibilityIsSwitchControlRunning();
}
- (BOOL)isMobileLandscape {
  return self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact;
}
- (BOOL)shouldPresentFullScreen {
  return [self isAccessibilityMode] ||
         (self.shouldDisplayMobileLandscapeFullscreen && [self isMobileLandscape]);
}

- (BOOL)contentReachesFullScreen {
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    return bottomDrawerPresentationController.contentReachesFullscreen;
  }
  return [self shouldPresentFullScreen];
}

- (void)setTopHandleHidden:(BOOL)topHandleHidden {
  _topHandleHidden = topHandleHidden;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.topHandleHidden = topHandleHidden;
  }
}

- (void)setTopHandleColor:(UIColor *)topHandleColor {
  _topHandleColor = topHandleColor;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.topHandleColor = topHandleColor;
  }
}

- (void)setMaximumInitialDrawerHeight:(CGFloat)maximumInitialDrawerHeight {
  _maximumInitialDrawerHeight = maximumInitialDrawerHeight;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.maximumInitialDrawerHeight = maximumInitialDrawerHeight;
  }
}

- (void)setMaximumDrawerHeight:(CGFloat)maximumDrawerHeight {
  _maximumDrawerHeight = maximumDrawerHeight;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.maximumDrawerHeight = maximumDrawerHeight;
  }
}

- (void)setDismissOnBackgroundTap:(BOOL)dismissOnBackgroundTap {
  _dismissOnBackgroundTap = dismissOnBackgroundTap;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.dismissOnBackgroundTap = self.dismissOnBackgroundTap;
  }
}

- (void)setShouldForwardBackgroundTouchEvents:(BOOL)shouldForwardBackgroundTouchEvents {
  _shouldForwardBackgroundTouchEvents = shouldForwardBackgroundTouchEvents;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.shouldForwardBackgroundTouchEvents =
        self.shouldForwardBackgroundTouchEvents;
  }
  if (shouldForwardBackgroundTouchEvents) {
    [self setDismissOnBackgroundTap:NO];
  }
}

- (void)setElevation:(MDCShadowElevation)elevation {
  _elevation = elevation;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    BOOL elevationDidChange =
        !MDCCGFloatEqual(bottomDrawerPresentationController.elevation, elevation);
    if (elevationDidChange) {
      bottomDrawerPresentationController.elevation = elevation;
      [self.view mdc_elevationDidChange];
    }
  }
}

- (void)setShouldAlwaysExpandHeader:(BOOL)shouldAlwaysExpandHeader {
  _shouldAlwaysExpandHeader = shouldAlwaysExpandHeader;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.shouldAlwaysExpandHeader = shouldAlwaysExpandHeader;
  }
}

- (void)setDelegate:(id<MDCBottomDrawerViewControllerDelegate>)delegate {
  _delegate = delegate;
  if ([delegate isKindOfClass:[UIResponder class]]) {
    _cachedNextResponder = (UIResponder *)delegate;
  } else {
    _cachedNextResponder = nil;
  }
}

- (UIResponder *)nextResponder {
  // Allow the delegate to opt-in to the responder chain to handle events.
  if (self.shouldForwardBackgroundTouchEvents && _cachedNextResponder) {
    return _cachedNextResponder;
  }

  // Otherwise, just follow the normal path.
  return [super nextResponder];
}

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

- (void)setDrawerShadowColor:(UIColor *)drawerShadowColor {
  _drawerShadowColor = drawerShadowColor;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.drawerShadowColor = drawerShadowColor;
  }
}

- (BOOL)userDraggingEnabled {
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    return bottomDrawerPresentationController.userDraggingEnabled;
  } else {
    return YES;
  }
}

- (void)setUserDraggingEnabled:(BOOL)userDraggingEnabled {
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.userDraggingEnabled = userDraggingEnabled;
  }
}

- (void)setShouldIncludeSafeAreaInContentHeight:(BOOL)shouldIncludeSafeAreaInContentHeight {
  _shouldIncludeSafeAreaInContentHeight = shouldIncludeSafeAreaInContentHeight;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.shouldIncludeSafeAreaInContentHeight =
        shouldIncludeSafeAreaInContentHeight;
  }
}

- (void)setShouldIncludeSafeAreaInInitialDrawerHeight:
    (BOOL)shouldIncludeSafeAreaInInitialDrawerHeight {
  _shouldIncludeSafeAreaInInitialDrawerHeight = shouldIncludeSafeAreaInInitialDrawerHeight;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.shouldIncludeSafeAreaInInitialDrawerHeight =
        shouldIncludeSafeAreaInInitialDrawerHeight;
  }
}

- (void)setShouldUseStickyStatusBar:(BOOL)shouldUseStickyStatusBar {
  _shouldUseStickyStatusBar = shouldUseStickyStatusBar;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.shouldUseStickyStatusBar = shouldUseStickyStatusBar;
  }
}

- (void)setShouldAdjustOnContentSizeChange:(BOOL)shouldAdjustOnContentSizeChange {
  _shouldAdjustOnContentSizeChange = shouldAdjustOnContentSizeChange;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.shouldAdjustOnContentSizeChange =
        shouldAdjustOnContentSizeChange;
  }
}

#pragma mark UIAccessibilityAction

// Adds the Z gesture for dismissal.
- (BOOL)accessibilityPerformEscape {
  if (!self.shouldDismissOnAccessibilityPerformEscape) {
    return NO;
  }

  [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
  return YES;
}

- (void)bottomDrawerTopTransitionRatio:
            (nonnull MDCBottomDrawerPresentationController *)presentationController
                       transitionRatio:(CGFloat)transitionRatio {
  [_maskLayer animateWithPercentage:1 - transitionRatio];
  if (self.delegate) {
    [self contentDrawerTopInset:transitionRatio];
  }
}

- (void)bottomDrawerPresentTransitionDidEnd:
    (MDCBottomDrawerPresentationController *)presentationController {
  if ([self.delegate respondsToSelector:@selector(bottomDrawerControllerDidEndOpenTransition:)]) {
    [self.delegate bottomDrawerControllerDidEndOpenTransition:self];
  }
}

- (void)bottomDrawerDismissTransitionDidEnd:
    (MDCBottomDrawerPresentationController *)presentationController {
  _isDrawerClosed = YES;
  if ([self.delegate respondsToSelector:@selector(bottomDrawerControllerDidEndCloseTransition:)]) {
    [self.delegate bottomDrawerControllerDidEndCloseTransition:self];
  }
}

- (void)bottomDrawerDidTapScrim:(MDCBottomDrawerPresentationController *)presentationController {
  if ([self.delegate respondsToSelector:@selector(bottomDrawerControllerDidTapScrim:)]) {
    [self.delegate bottomDrawerControllerDidTapScrim:self];
  }
}

- (void)bottomDrawerPresentTransitionWillBegin:
            (MDCBottomDrawerPresentationController *)presentationController
                               withCoordinator:
                                   (id<UIViewControllerTransitionCoordinator>)transitionCoordinator
                                 targetYOffset:(CGFloat)targetYOffset {
  _isDrawerClosed = NO;
  _lastOffset = targetYOffset;
  if ([self.delegate respondsToSelector:@selector
                     (bottomDrawerControllerWillTransitionOpen:withCoordinator:targetYOffset:)]) {
    [self.delegate bottomDrawerControllerWillTransitionOpen:self
                                            withCoordinator:transitionCoordinator
                                              targetYOffset:targetYOffset];
  }
}

- (void)bottomDrawerDismissTransitionWillBegin:
            (MDCBottomDrawerPresentationController *)presentationController
                               withCoordinator:
                                   (id<UIViewControllerTransitionCoordinator>)transitionCoordinator
                                 targetYOffset:(CGFloat)targetYOffset {
  _lastOffset = targetYOffset;
  if ([self.delegate respondsToSelector:@selector
                     (bottomDrawerControllerWillTransitionClosed:withCoordinator:targetYOffset:)]) {
    [self.delegate bottomDrawerControllerWillTransitionClosed:self
                                              withCoordinator:transitionCoordinator
                                                targetYOffset:targetYOffset];
  }
}

- (void)bottomDrawerTopDidChangeYOffset:
            (MDCBottomDrawerPresentationController *)presentationController
                                yOffset:(CGFloat)yOffset {
  // Only forward changes along if the drawer is actually still on screen and the offset has
  // changed. This will avoid sending thru duplicated offset changes or changes where the
  // real value will be calculated soon (aka set to zero for prep, then layout pass happens).
  if (!_isDrawerClosed && _lastOffset != yOffset &&
      [self.delegate respondsToSelector:@selector(bottomDrawerControllerDidChangeTopYOffset:
                                                                                    yOffset:)]) {
    [self.delegate bottomDrawerControllerDidChangeTopYOffset:self yOffset:yOffset];
  }
  _lastOffset = yOffset;
}

- (void)bottomDrawerWillChangeState:
            (nonnull MDCBottomDrawerPresentationController *)presentationController
                        drawerState:(MDCBottomDrawerState)drawerState {
  _drawerState = drawerState;
  CGFloat minimumCornerRadius = [self minimumCornerRadius];
  if (_maskLayer.minimumCornerRadius != minimumCornerRadius) {
    _maskLayer.minimumCornerRadius = minimumCornerRadius;
    [_maskLayer applyMask];
  }
}

- (void)contentDrawerTopInset:(CGFloat)transitionToTop {
  CGFloat topInset = MDCFixedStatusBarHeightOnPreiPhoneXDevices;
  if (@available(iOS 11.0, *)) {
    topInset = self.view.safeAreaInsets.top;
  }

  if ([self contentReachesFullScreen]) {
    topInset -= ((CGFloat)1.0 - transitionToTop) * topInset;
  } else {
    topInset = (CGFloat)0.0;
  }
  if (!self.topHandleHidden) {
    topInset = MAX(topInset, (CGFloat)7.0);
  }

  if ([self.delegate respondsToSelector:@selector(bottomDrawerControllerDidChangeTopInset:
                                                                                 topInset:)]) {
    [self.delegate bottomDrawerControllerDidChangeTopInset:self topInset:topInset];
  }
}

- (void)setContentOffsetY:(CGFloat)contentOffsetY animated:(BOOL)animated {
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    [bottomDrawerPresentationController setContentOffsetY:contentOffsetY animated:animated];
  }
}

- (void)expandToFullscreenWithDuration:(CGFloat)duration
                            completion:(void (^__nullable)(BOOL finished))completion {
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    [bottomDrawerPresentationController expandToFullscreenWithDuration:duration
                                                            completion:completion];
  }
}

- (void)setAdjustLayoutForIPadSlideOver:(BOOL)adjustLayoutForIPadSlideOver {
  _adjustLayoutForIPadSlideOver = adjustLayoutForIPadSlideOver;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.adjustLayoutForIPadSlideOver =
        self.adjustLayoutForIPadSlideOver;
  }
}

- (void)setShouldDisplayMobileLandscapeFullscreen:(BOOL)shouldDisplayMobileLandscapeFullscreen {
  _shouldDisplayMobileLandscapeFullscreen = shouldDisplayMobileLandscapeFullscreen;
  if ([self.presentationController isKindOfClass:[MDCBottomDrawerPresentationController class]]) {
    MDCBottomDrawerPresentationController *bottomDrawerPresentationController =
        (MDCBottomDrawerPresentationController *)self.presentationController;
    bottomDrawerPresentationController.shouldDisplayMobileLandscapeFullscreen =
        self.shouldDisplayMobileLandscapeFullscreen;
  }
}

@end
