// Copyright 2017-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import "MDCShapedShadowLayer.h"

#import "MDCShapeGenerating.h"
#import "MaterialColor.h"

// An epsilon for use with width/height values.
static const CGFloat kDimensionalEpsilon = 0.001;

@implementation MDCShapedShadowLayer

- (instancetype)init {
  self = [super init];
  if (self) {
    [self commonMDCShapedShadowLayerInit];
  }
  return self;
}

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

- (instancetype)initWithLayer:(id)layer {
  self = [super initWithLayer:layer];
  if (self && [self isKindOfClass:[MDCShapedShadowLayer class]]) {
    MDCShapedShadowLayer *otherLayer = (MDCShapedShadowLayer *)layer;
    _shapeGenerator = [otherLayer.shapeGenerator copyWithZone:NULL];
    _colorLayer = (CAShapeLayer *)layer;
  }
  return self;
}

- (void)commonMDCShapedShadowLayerInit {
  self.backgroundColor = [UIColor clearColor].CGColor;
  _colorLayer = [CAShapeLayer layer];
  _colorLayer.delegate = self;
  _shapeLayer = [CAShapeLayer layer];
  [self addSublayer:_colorLayer];
}

- (void)layoutSublayers {
  [super layoutSublayers];

  CGRect bounds = self.bounds;
  CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
  _colorLayer.position = center;
  _colorLayer.bounds = bounds;
}

- (void)prepareShadowPath {
  if (self.shapeGenerator) {
    CGRect standardizedBounds = CGRectStandardize(self.bounds);
    self.path = [self.shapeGenerator pathForSize:standardizedBounds.size];
  }
}

- (void)setShapeGenerator:(id<MDCShapeGenerating>)shapeGenerator {
  _shapeGenerator = shapeGenerator;

  CGRect standardizedBounds = CGRectStandardize(self.bounds);
  self.path = [self.shapeGenerator pathForSize:standardizedBounds.size];
}

- (void)setPath:(CGPathRef)path {
  self.shadowPath = path;
  _colorLayer.path = path;
  _shapeLayer.path = path;

  if (CGPathIsEmpty(path)) {
    self.backgroundColor = self.shapedBackgroundColor.CGColor;
    self.borderColor = self.shapedBorderColor.CGColor;
    self.borderWidth = self.shapedBorderWidth;

    _colorLayer.fillColor = nil;
    _colorLayer.strokeColor = nil;
    _colorLayer.lineWidth = 0;
  } else {
    self.backgroundColor = nil;
    self.borderColor = nil;
    self.borderWidth = 0;

    _colorLayer.fillColor = self.shapedBackgroundColor.CGColor;
    _colorLayer.strokeColor = self.shapedBorderColor.CGColor;
    _colorLayer.lineWidth = self.shapedBorderWidth;
    [self generateColorPathGivenLineWidth];
  }
}

- (void)generateColorPathGivenLineWidth {
  if (CGPathIsEmpty(self.path) || _colorLayer.lineWidth <= 0) {
    _colorLayer.path = self.shadowPath;
    _shapeLayer.path = self.shadowPath;
    return;
  }
  CGFloat halfOfBorderWidth = self.shapedBorderWidth / 2.f;
  CGAffineTransform colorLayerTransform = [self generateTransformInsetByValue:halfOfBorderWidth];
  CGPathRef colorLayerPath =
      CGPathCreateCopyByTransformingPath(self.shadowPath, &colorLayerTransform);
  _colorLayer.path = colorLayerPath;
  CGPathRelease(colorLayerPath);
  // The shape layer is used to provide the user a mask for their content, which means also
  // show the full border. Because the border is shown half outside and half inside
  // the color layer path, we must inset the shape layer by the full border width.
  CGAffineTransform shapeLayerTransform =
      [self generateTransformInsetByValue:self.shapedBorderWidth];
  CGPathRef shapeLayerPath =
      CGPathCreateCopyByTransformingPath(self.shadowPath, &shapeLayerTransform);
  _shapeLayer.path = shapeLayerPath;
  CGPathRelease(shapeLayerPath);
}

- (CGAffineTransform)generateTransformInsetByValue:(CGFloat)value {
  // Use the identitfy transfrom when inset is less than Epsilon.
  if (value < kDimensionalEpsilon) {
    return CGAffineTransformIdentity;
  }

  // Use the path's boundingBox to get the proportion of inset value,
  // because this tranform is expected to be applied on a CGPath.
  CGRect pathBoundingBox = CGPathGetPathBoundingBox(self.shadowPath);
  CGRect pathStandardizedBounds = CGRectStandardize(pathBoundingBox);

  if (CGRectGetWidth(pathStandardizedBounds) < kDimensionalEpsilon ||
      CGRectGetHeight(pathStandardizedBounds) < kDimensionalEpsilon) {
    return CGAffineTransformIdentity;
  }

  CGRect insetBounds = CGRectInset(pathStandardizedBounds, value, value);
  CGFloat width = CGRectGetWidth(pathStandardizedBounds);
  CGFloat height = CGRectGetHeight(pathStandardizedBounds);
  CGFloat pathCenterX = CGRectGetMidX(pathStandardizedBounds);
  CGFloat pathCenterY = CGRectGetMidY(pathStandardizedBounds);
  // Calculate the shifted center and re-center it by applying a translation transform.
  // value * 2 represents the accumulated borderWidth on each side, value * 2 / width
  // represents the proportion of accumulated borderWidth in path bounds, which is also
  // the value used for scale transform.
  // The shiftWidth represents the shifted length horizontally on the center.
  CGFloat shiftWidth = value * 2 / width * pathCenterX;
  // Same calculation for height.
  CGFloat shiftHeight = value * 2 / height * pathCenterY;
  CGAffineTransform transform = CGAffineTransformMakeTranslation(shiftWidth, shiftHeight);
  transform = CGAffineTransformScale(transform, CGRectGetWidth(insetBounds) / width,
                                     CGRectGetHeight(insetBounds) / height);
  return transform;
}

- (CGPathRef)path {
  return _colorLayer.path;
}

- (void)setShapedBackgroundColor:(UIColor *)shapedBackgroundColor {
  _shapedBackgroundColor = shapedBackgroundColor;

  if ([self.delegate isKindOfClass:[UIView class]]) {
    UIView *view = (UIView *)self.delegate;
    _shapedBackgroundColor =
        [_shapedBackgroundColor mdc_resolvedColorWithTraitCollection:view.traitCollection];
  }

  if (CGPathIsEmpty(self.path)) {
    self.backgroundColor = _shapedBackgroundColor.CGColor;
    _colorLayer.fillColor = nil;
  } else {
    self.backgroundColor = nil;
    _colorLayer.fillColor = _shapedBackgroundColor.CGColor;
  }
}

- (void)setShapedBorderColor:(UIColor *)shapedBorderColor {
  _shapedBorderColor = shapedBorderColor;

  if ([self.delegate isKindOfClass:[UIView class]]) {
    UIView *view = (UIView *)self.delegate;
    _shapedBorderColor =
        [_shapedBorderColor mdc_resolvedColorWithTraitCollection:view.traitCollection];
  }
  if (CGPathIsEmpty(self.path)) {
    self.borderColor = _shapedBorderColor.CGColor;
    _colorLayer.strokeColor = nil;
  } else {
    self.borderColor = nil;
    _colorLayer.strokeColor = _shapedBorderColor.CGColor;
  }
}

- (void)setShapedBorderWidth:(CGFloat)shapedBorderWidth {
  _shapedBorderWidth = shapedBorderWidth;

  if (CGPathIsEmpty(self.path)) {
    self.borderWidth = _shapedBorderWidth;
    _colorLayer.lineWidth = 0;
  } else {
    self.borderWidth = 0;
    _colorLayer.lineWidth = _shapedBorderWidth;
    [self generateColorPathGivenLineWidth];
  }
}

@end
