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

#import "MDCTextInput.h"
#import "MDCTextInputBorderView.h"
#import "MDCTextInputUnderlineView.h"
#import "private/MDCTextInputControllerBase+Subclassing.h"

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"

#pragma mark - Class Properties

static const CGFloat MDCTextInputOutlinedTextFieldFloatingPlaceholderPadding = 8;
static const CGFloat MDCTextInputOutlinedTextFieldFullPadding = 16;
static const CGFloat MDCTextInputOutlinedTextFieldNormalPlaceholderPadding = 20;
static const CGFloat MDCTextInputOutlinedTextFieldThreeQuartersPadding = 12;

static UIRectCorner _roundedCornersDefault = UIRectCornerAllCorners;

@interface MDCTextInputControllerOutlined ()

@property(nonatomic, strong) NSLayoutConstraint *placeholderCenterY;
@property(nonatomic, strong) NSLayoutConstraint *placeholderLeading;

@end

@implementation MDCTextInputControllerOutlined

- (instancetype)initWithTextInput:(UIView<MDCTextInput> *)input {
  NSAssert(![input conformsToProtocol:@protocol(MDCMultilineTextInput)],
           @"This design is meant for single-line text fields only. For a complementary multi-line "
           @"style, see MDCTextInputControllerOutlinedTextArea.");
  self = [super initWithTextInput:input];
  if (self) {
    input.textInsetsMode = MDCTextInputTextInsetsModeAlways;
  }
  return self;
}

#pragma mark - Properties Implementations

- (BOOL)isFloatingEnabled {
  return YES;
}

- (void)setFloatingEnabled:(__unused BOOL)floatingEnabled {
  // Unused. Floating is always enabled.
}

- (UIOffset)floatingPlaceholderOffset {
  UIOffset offset = [super floatingPlaceholderOffset];
  CGFloat textVerticalOffset = 0;
  offset.vertical = textVerticalOffset;
  return offset;
}

+ (UIRectCorner)roundedCornersDefault {
  return _roundedCornersDefault;
}

+ (void)setRoundedCornersDefault:(UIRectCorner)roundedCornersDefault {
  _roundedCornersDefault = roundedCornersDefault;
}

#pragma mark - MDCTextInputPositioningDelegate

- (CGRect)leadingViewRectForBounds:(CGRect)bounds defaultRect:(CGRect)defaultRect {
  CGRect leadingViewRect = defaultRect;
  CGFloat xOffset = (self.textInput.effectiveUserInterfaceLayoutDirection ==
                     UIUserInterfaceLayoutDirectionRightToLeft)
                        ? -1 * MDCTextInputOutlinedTextFieldFullPadding
                        : MDCTextInputOutlinedTextFieldFullPadding;

  leadingViewRect = CGRectOffset(leadingViewRect, xOffset, 0);

  CGRect borderRect = [self borderRect];
  leadingViewRect.origin.y = CGRectGetMinY(borderRect) + CGRectGetHeight(borderRect) / 2 -
                             CGRectGetHeight(leadingViewRect) / 2;

  return leadingViewRect;
}

- (CGFloat)leadingViewTrailingPaddingConstant {
  return MDCTextInputOutlinedTextFieldFullPadding;
}

- (CGRect)trailingViewRectForBounds:(CGRect)bounds defaultRect:(CGRect)defaultRect {
  CGRect trailingViewRect = defaultRect;
  CGFloat xOffset = (self.textInput.effectiveUserInterfaceLayoutDirection ==
                     UIUserInterfaceLayoutDirectionRightToLeft)
                        ? MDCTextInputOutlinedTextFieldThreeQuartersPadding
                        : -1 * MDCTextInputOutlinedTextFieldThreeQuartersPadding;

  trailingViewRect = CGRectOffset(trailingViewRect, xOffset, 0);

  CGRect borderRect = [self borderRect];
  trailingViewRect.origin.y = CGRectGetMinY(borderRect) + CGRectGetHeight(borderRect) / 2 -
                              CGRectGetHeight(trailingViewRect) / 2;

  return trailingViewRect;
}

- (CGFloat)trailingViewTrailingPaddingConstant {
  return MDCTextInputOutlinedTextFieldThreeQuartersPadding;
}

// clang-format off
/**
 textInsets: is the source of truth for vertical layout. It's used to figure out the proper
 height and also where to place the placeholder / text field.

 NOTE: It's applied before the textRect is flipped for RTL. So all calculations are done here à la
 LTR.

 This one is a little different because the placeholder crosses the top bordered area when floating.

 The vertical layout is, at most complex, this form:

 placeholderEstimatedHeight                                           // Height of placeholder
 MDCTextInputOutlinedTextFieldFullPadding                             // Padding
 ceil(MAX(self.textInput.font.lineHeight,                          // Text field or placeholder
             self.textInput.placeholderLabel.font.lineHeight))
 MDCTextInputControllerBaseDefaultPadding                             // Padding to bottom of border rect
 underlineLabelsOffset                                                // From super class.
 */
// clang-format on
- (UIEdgeInsets)textInsets:(UIEdgeInsets)defaultInsets
    withSizeThatFitsWidthHint:(CGFloat)widthHint {
  defaultInsets.left = MDCTextInputOutlinedTextFieldFullPadding;
  defaultInsets.right = MDCTextInputOutlinedTextFieldFullPadding;
  UIEdgeInsets textInsets = [super textInsets:defaultInsets withSizeThatFitsWidthHint:widthHint];
  CGFloat textVerticalOffset = self.textInput.placeholderLabel.font.lineHeight * (CGFloat)0.5;

  CGFloat scale = UIScreen.mainScreen.scale;
  CGFloat placeholderEstimatedHeight =
      ceil(self.textInput.placeholderLabel.font.lineHeight * scale) / scale;
  textInsets.top = [self borderHeight] - MDCTextInputOutlinedTextFieldFullPadding -
                   placeholderEstimatedHeight + textVerticalOffset;

  return textInsets;
}

#pragma mark - MDCTextInputControllerBase overrides

- (void)updateLayout {
  [super updateLayout];

  self.textInput.clipsToBounds = NO;
}

- (void)updateUnderline {
  self.textInput.underline.hidden = YES;
}

- (void)updateBorder {
  [super updateBorder];

  UIBezierPath *path;
  if ([self isPlaceholderUp]) {
    CGFloat placeholderWidth = 0;
    NSString *placeholderString = [self.textInput.placeholderLabel.text
        stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
    if (placeholderString.length > 0) {
      placeholderWidth = [self.textInput.placeholderLabel
                             systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]
                             .width *
                         (CGFloat)self.floatingPlaceholderScale.floatValue;
      placeholderWidth += MDCTextInputOutlinedTextFieldFloatingPlaceholderPadding;
    }

    path = [self roundedPathFromRect:[self borderRect]
                       withTextSpace:placeholderWidth
                       leadingOffset:MDCTextInputOutlinedTextFieldFullPadding -
                                     MDCTextInputOutlinedTextFieldFloatingPlaceholderPadding / 2];
  } else {
    CGSize cornerRadius = CGSizeMake(self.borderRadius, self.borderRadius);
    path = [UIBezierPath bezierPathWithRoundedRect:[self borderRect]
                                 byRoundingCorners:self.roundedCorners
                                       cornerRadii:cornerRadius];
  }
  self.textInput.borderPath = path;

  UIColor *borderColor =
      self.textInput.isEditing ? self.activeColor : (self.borderStrokeColor ?: self.normalColor);
  if (!self.textInput.isEnabled) {
    borderColor = self.disabledColor;
  }
  self.textInput.borderView.borderStrokeColor =
      (self.isDisplayingCharacterCountError || self.isDisplayingErrorText) ? self.errorColor
                                                                           : borderColor;
  self.textInput.borderView.borderPath.lineWidth = self.textInput.isEditing ? 2 : 1;

  [self.textInput.borderView setNeedsLayout];

  [self updatePlaceholder];
}

- (CGRect)borderRect {
  CGRect pathRect = self.textInput.bounds;
  pathRect.origin.y =
      pathRect.origin.y + self.textInput.placeholderLabel.font.lineHeight * (CGFloat)0.5;
  pathRect.size.height = [self borderHeight];
  return pathRect;
}

- (UIBezierPath *)roundedPathFromRect:(CGRect)f
                        withTextSpace:(CGFloat)textSpace
                        leadingOffset:(CGFloat)offset {
  UIBezierPath *path = [[UIBezierPath alloc] init];
  CGFloat radius = self.borderRadius;
  CGFloat yOffset = f.origin.y;
  CGFloat xOffset = f.origin.x;

  // Draw the path
  [path moveToPoint:CGPointMake(radius + xOffset, yOffset)];
  if (self.textInput.effectiveUserInterfaceLayoutDirection ==
      UIUserInterfaceLayoutDirectionLeftToRight) {
    [path addLineToPoint:CGPointMake(offset + xOffset, yOffset)];
    [path moveToPoint:CGPointMake(textSpace + offset + xOffset, yOffset)];
    [path addLineToPoint:CGPointMake(f.size.width - radius + xOffset, yOffset)];
  } else {
    [path addLineToPoint:CGPointMake(xOffset + (f.size.width - (offset + textSpace)), yOffset)];
    [path moveToPoint:CGPointMake(xOffset + (f.size.width - offset), yOffset)];
    [path addLineToPoint:CGPointMake(xOffset + (f.size.width - radius), yOffset)];
  }

  [path addArcWithCenter:CGPointMake(f.size.width - radius + xOffset, radius + yOffset)
                  radius:radius
              startAngle:-(CGFloat)(M_PI / 2)
                endAngle:0
               clockwise:YES];
  [path addLineToPoint:CGPointMake(f.size.width + xOffset, f.size.height - radius + yOffset)];
  [path addArcWithCenter:CGPointMake(f.size.width - radius + xOffset,
                                     f.size.height - radius + yOffset)
                  radius:radius
              startAngle:0
                endAngle:-(CGFloat)((M_PI * 3) / 2)
               clockwise:YES];
  [path addLineToPoint:CGPointMake(radius + xOffset, f.size.height + yOffset)];
  [path addArcWithCenter:CGPointMake(radius + xOffset, f.size.height - radius + yOffset)
                  radius:radius
              startAngle:-(CGFloat)((M_PI * 3) / 2)
                endAngle:-(CGFloat)M_PI
               clockwise:YES];
  [path addLineToPoint:CGPointMake(xOffset, radius + yOffset)];
  [path addArcWithCenter:CGPointMake(radius + xOffset, radius + yOffset)
                  radius:radius
              startAngle:-(CGFloat)M_PI
                endAngle:-(CGFloat)(M_PI / 2)
               clockwise:YES];

  return path;
}

- (void)updatePlaceholder {
  [super updatePlaceholder];

  CGFloat scale = UIScreen.mainScreen.scale;
  CGFloat placeholderEstimatedHeight =
      ceil(self.textInput.placeholderLabel.font.lineHeight * scale) / scale;
  CGFloat placeholderConstant = ([self borderHeight] / 2) - (placeholderEstimatedHeight / 2) +
                                self.textInput.placeholderLabel.font.lineHeight * (CGFloat)0.5;
  if (!self.placeholderCenterY) {
    self.placeholderCenterY = [NSLayoutConstraint constraintWithItem:self.textInput.placeholderLabel
                                                           attribute:NSLayoutAttributeTop
                                                           relatedBy:NSLayoutRelationEqual
                                                              toItem:self.textInput
                                                           attribute:NSLayoutAttributeTop
                                                          multiplier:1
                                                            constant:placeholderConstant];
    self.placeholderCenterY.priority = UILayoutPriorityDefaultHigh;
    self.placeholderCenterY.active = YES;

    [self.textInput.placeholderLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh + 1
                                                       forAxis:UILayoutConstraintAxisVertical];
  }
  self.placeholderCenterY.constant = placeholderConstant;

  CGFloat placeholderLeadingConstant = MDCTextInputOutlinedTextFieldFullPadding;

  if ([self.textInput conformsToProtocol:@protocol(MDCLeadingViewTextInput)]) {
    UIView<MDCLeadingViewTextInput> *leadingViewInput =
        (UIView<MDCLeadingViewTextInput> *)self.textInput;
    if (leadingViewInput.leadingView.superview) {
      placeholderLeadingConstant += CGRectGetWidth(leadingViewInput.leadingView.frame) +
                                    [self leadingViewTrailingPaddingConstant];
    }
  }

  if (!self.placeholderLeading) {
    self.placeholderLeading = [NSLayoutConstraint constraintWithItem:self.textInput.placeholderLabel
                                                           attribute:NSLayoutAttributeLeading
                                                           relatedBy:NSLayoutRelationEqual
                                                              toItem:self.textInput
                                                           attribute:NSLayoutAttributeLeading
                                                          multiplier:1
                                                            constant:placeholderLeadingConstant];
    self.placeholderLeading.priority = UILayoutPriorityDefaultHigh;
    self.placeholderLeading.active = YES;
  }
  self.placeholderLeading.constant = placeholderLeadingConstant;
}

- (CGFloat)borderHeight {
  CGFloat scale = UIScreen.mainScreen.scale;
  CGFloat placeholderEstimatedHeight =
      ceil(self.textInput.placeholderLabel.font.lineHeight * scale) / scale;
  return MDCTextInputOutlinedTextFieldNormalPlaceholderPadding + placeholderEstimatedHeight +
         MDCTextInputOutlinedTextFieldNormalPlaceholderPadding;
}

@end

#pragma clang diagnostic pop
