<commit_before>//
//  Created by <NAME> on 12/13/15.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import UIKit

public protocol MaskDesignable {
  var maskType: MaskType { get set }
}

public extension MaskDesignable where Self: UIView {
  
  public func configMask() {
    
    switch maskType {
    case .circle:
      maskCircle()
    case .parallelogram(let angle):
      maskParallelogram(angle ?? 60)
    case .polygon(let sides):
      maskPolygon(sides ?? 6)
    case .star(let points):
      maskStar(points ?? 5)
    case .wave(let direction, let width, let offset):
      maskWave(direction ?? .up, waveWidth: width ?? 40.0, waveOffset:offset ?? 0.0)
    case .triangle:
      maskTriangle()
    case .none:
      return
    }
  }
  
  // MARK: - Circle
  
  
  private func maskCircle() {
    let diameter = ceil(min(bounds.width, bounds.height))
    let origin = CGPoint(x: (bounds.width - diameter) / 2.0, y: (bounds.height - diameter) / 2.0)
    let size = CGSize(width: diameter, height: diameter)
    let circlePath = UIBezierPath(ovalIn: CGRect(origin: origin, size: size))
    drawPath(circlePath)
  }
  
  // MARK: - Polygon
  
  private func maskPolygon(_ sides: Int = 6) {
    let polygonPath = maskPolygonBezierPath(max(sides, 3))
    drawPath(polygonPath)
  }
  
  private func maskPolygonBezierPath(_ sides: Int) -> UIBezierPath {
    let path = UIBezierPath()
    let center = CGPoint(x: bounds.width / 2.0, y: bounds.height / 2.0)
    var angle: CGFloat = -.pi / 2
    let angleIncrement = .pi * 2 / CGFloat(sides)
    let length = min(bounds.width, bounds.height)
    let radius = length / 2.0
    
    path.move(to: pointFrom(angle, radius: radius, offset: center))
    for _ in 1...sides - 1 {
      angle += angleIncrement
      path.addLine(to: pointFrom(angle, radius: radius, offset: center))
    }
    path.close()
    return path
  }
  
  // MARK: - Star
  
  // See https://www.weheartswift.com/bezier-paths-gesture-recognizers/
  private func maskStar(_ points: Int = 5) {
    // FIXME: Do not mask the shadow.
    
    // Stars must has at least 3 points.
    var starPoints = points
    if points <= 2 {
      starPoints = 5
    }
    
    let path = starPath(starPoints)
    drawPath(path)
  }
  
  private func starPath(_ points: Int, borderWidth: CGFloat = 0) -> UIBezierPath {
    let path = UIBezierPath()
    let radius = min(bounds.size.width, bounds.size.height) / 2 - borderWidth
    let starExtrusion = radius / 2
    let angleIncrement = .pi * 2 / CGFloat(points)
    let center = CGPoint(x: bounds.width / 2.0, y: bounds.height / 2.0)
    var angle: CGFloat = -.pi / 2
    var firstPoint = true
    for _ in 1...points {
      let point = pointFrom(angle, radius: radius, offset: center)
      let nextPoint = pointFrom(angle + angleIncrement, radius: radius, offset: center)
      let midPoint = pointFrom(angle + angleIncrement / 2.0, radius: starExtrusion, offset: center)
      
      if firstPoint {
        firstPoint = false
        path.move(to: point)
      }
      
      path.addLine(to: midPoint)
      path.addLine(to: nextPoint)
      angle += angleIncrement
    }
    
    path.close()
    return path
  }
  
  // MARK: - Parallelogram
  
  private func maskParallelogram(_ topLeftAngle: Double = 60) {
    let parallelogramPath = maskParallelogramBezierPath(topLeftAngle)
    drawPath(parallelogramPath)
  }
  
  private func maskParallelogramBezierPath(_ topLeftAngle: Double) -> UIBezierPath {
    let topLeftAngleRad = topLeftAngle * .pi / 180
    let path = UIBezierPath()
    let offset = abs(CGFloat(tan(topLeftAngleRad - .pi / 2)) * bounds.height)
    
    if topLeftAngle <= 90 {
      path.move(to: CGPoint(x:0, y:0))
      path.addLine(to: CGPoint(x: bounds.width - offset, y: 0))
      path.addLine(to: CGPoint(x:bounds.width, y:bounds.height))
      path.addLine(to: CGPoint(x: offset, y: bounds.height))
    } else {
      path.move(to: CGPoint(x:offset, y:0))
      path.addLine(to: CGPoint(x:bounds.width, y:0))
      path.addLine(to: CGPoint(x:bounds.width - offset, y:bounds.height))
      path.addLine(to: CGPoint(x:0, y:bounds.height))
    }
    path.close()
    return path
  }
  
  // MARK: - Triangle
  
  private func maskTriangle() {
    let trianglePath = maskTriangleBezierPath()
    drawPath(trianglePath)
  }
  
  private func maskTriangleBezierPath() -> UIBezierPath {
    let path = UIBezierPath()
    
    path.move(to: CGPoint(x: bounds.width / 2.0, y: bounds.origin.y))
    path.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
    path.addLine(to: CGPoint(x: bounds.origin.x, y: bounds.height))
    path.close()
    return path
  }
  
  // MARK: - Wave
  
  
  private func maskWave(_ waveDirection: MaskType.WaveDirection, waveWidth: Float = 40.0, waveOffset: Float = 0.0) {
    let wavePath = maskWaveBezierPath(waveDirection == .up, waveWidth: CGFloat(waveWidth), waveOffset: CGFloat(waveOffset))
    drawPath(wavePath)
  }
  
  private func maskWaveBezierPath(_ waveUp: Bool, waveWidth: CGFloat, waveOffset: CGFloat) -> UIBezierPath {
    let originY = waveUp ? bounds.maxY : bounds.minY
    let halfWidth = waveWidth / 2.0
    let halfHeight = bounds.height / 2.0
    let quarterWidth = waveWidth / 4.0
    
    var up = waveUp
    var startX = bounds.minX - quarterWidth - (waveOffset.truncatingRemainder(dividingBy: waveWidth))
    var endX = startX + halfWidth
    
    let path = UIBezierPath()
    path.move(to: CGPoint(x: startX, y: originY))
    path.addLine(to: CGPoint(x: startX, y: bounds.midY))
    
    repeat {
      path.addQuadCurve(
        to: CGPoint(x: endX, y: bounds.midY),
        controlPoint: CGPoint(
          x: startX + quarterWidth,
          y: up ? bounds.maxY + halfHeight : bounds.minY - halfHeight)
      )
      startX = endX<commit_msg>Remove redundant default values.<commit_after>//
//  Created by <NAME> on 12/13/15.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import UIKit

public protocol MaskDesignable {
  var maskType: MaskType { get set }
}

public extension MaskDesignable where Self: UIView {
  
  public func configMask() {
    
    switch maskType {
    case .circle:
      maskCircle()
    case .parallelogram(let angle):
      maskParallelogram(angle ?? 60)
    case .polygon(let sides):
      maskPolygon(sides ?? 6)
    case .star(let points):
      maskStar(points ?? 5)
    case .wave(let direction, let width, let offset):
      maskWave(direction ?? .up, waveWidth: width ?? 40.0, waveOffset:offset ?? 0.0)
    case .triangle:
      maskTriangle()
    case .none:
      return
    }
  }
  
  // MARK: - Circle
  
  
  private func maskCircle() {
    let diameter = ceil(min(bounds.width, bounds.height))
    let origin = CGPoint(x: (bounds.width - diameter) / 2.0, y: (bounds.height - diameter) / 2.0)
    let size = CGSize(width: diameter, height: diameter)
    let circlePath = UIBezierPath(ovalIn: CGRect(origin: origin, size: size))
    drawPath(circlePath)
  }
  
  // MARK: - Polygon
  
  private func maskPolygon(_ sides: Int) {
    let polygonPath = maskPolygonBezierPath(max(sides, 3))
    drawPath(polygonPath)
  }
  
  private func maskPolygonBezierPath(_ sides: Int) -> UIBezierPath {
    let path = UIBezierPath()
    let center = CGPoint(x: bounds.width / 2.0, y: bounds.height / 2.0)
    var angle: CGFloat = -.pi / 2
    let angleIncrement = .pi * 2 / CGFloat(sides)
    let length = min(bounds.width, bounds.height)
    let radius = length / 2.0
    
    path.move(to: pointFrom(angle, radius: radius, offset: center))
    for _ in 1...sides - 1 {
      angle += angleIncrement
      path.addLine(to: pointFrom(angle, radius: radius, offset: center))
    }
    path.close()
    return path
  }
  
  // MARK: - Star
  
  // See https://www.weheartswift.com/bezier-paths-gesture-recognizers/
  private func maskStar(_ points: Int) {
    // FIXME: Do not mask the shadow.
    
    // Stars must has at least 3 points.
    var starPoints = points
    if points <= 2 {
      starPoints = 5
    }
    
    let path = starPath(starPoints)
    drawPath(path)
  }
  
  private func starPath(_ points: Int, borderWidth: CGFloat = 0) -> UIBezierPath {
    let path = UIBezierPath()
    let radius = min(bounds.size.width, bounds.size.height) / 2 - borderWidth
    let starExtrusion = radius / 2
    let angleIncrement = .pi * 2 / CGFloat(points)
    let center = CGPoint(x: bounds.width / 2.0, y: bounds.height / 2.0)
    var angle: CGFloat = -.pi / 2
    var firstPoint = true
    for _ in 1...points {
      let point = pointFrom(angle, radius: radius, offset: center)
      let nextPoint = pointFrom(angle + angleIncrement, radius: radius, offset: center)
      let midPoint = pointFrom(angle + angleIncrement / 2.0, radius: starExtrusion, offset: center)
      
      if firstPoint {
        firstPoint = false
        path.move(to: point)
      }
      
      path.addLine(to: midPoint)
      path.addLine(to: nextPoint)
      angle += angleIncrement
    }
    
    path.close()
    return path
  }
  
  // MARK: - Parallelogram
  
  private func maskParallelogram(_ topLeftAngle: Double) {
    let parallelogramPath = maskParallelogramBezierPath(topLeftAngle)
    drawPath(parallelogramPath)
  }
  
  private func maskParallelogramBezierPath(_ topLeftAngle: Double) -> UIBezierPath {
    let topLeftAngleRad = topLeftAngle * .pi / 180
    let path = UIBezierPath()
    let offset = abs(CGFloat(tan(topLeftAngleRad - .pi / 2)) * bounds.height)
    
    if topLeftAngle <= 90 {
      path.move(to: CGPoint(x:0, y:0))
      path.addLine(to: CGPoint(x: bounds.width - offset, y: 0))
      path.addLine(to: CGPoint(x:bounds.width, y:bounds.height))
      path.addLine(to: CGPoint(x: offset, y: bounds.height))
    } else {
      path.move(to: CGPoint(x:offset, y:0))
      path.addLine(to: CGPoint(x:bounds.width, y:0))
      path.addLine(to: CGPoint(x:bounds.width - offset, y:bounds.height))
      path.addLine(to: CGPoint(x:0, y:bounds.height))
    }
    path.close()
    return path
  }
  
  // MARK: - Triangle
  
  private func maskTriangle() {
    let trianglePath = maskTriangleBezierPath()
    drawPath(trianglePath)
  }
  
  private func maskTriangleBezierPath() -> UIBezierPath {
    let path = UIBezierPath()
    
    path.move(to: CGPoint(x: bounds.width / 2.0, y: bounds.origin.y))
    path.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
    path.addLine(to: CGPoint(x: bounds.origin.x, y: bounds.height))
    path.close()
    return path
  }
  
  // MARK: - Wave
  
  
  private func maskWave(_ waveDirection: MaskType.WaveDirection, waveWidth: Float , waveOffset: Float) {
    let wavePath = maskWaveBezierPath(waveDirection == .up, waveWidth: CGFloat(waveWidth), waveOffset: CGFloat(waveOffset))
    drawPath(wavePath)
  }
  
  private func maskWaveBezierPath(_ waveUp: Bool, waveWidth: CGFloat, waveOffset: CGFloat) -> UIBezierPath {
    let originY = waveUp ? bounds.maxY : bounds.minY
    let halfWidth = waveWidth / 2.0
    let halfHeight = bounds.height / 2.0
    let quarterWidth = waveWidth / 4.0
    
    var up = waveUp
    var startX = bounds.minX - quarterWidth - (waveOffset.truncatingRemainder(dividingBy: waveWidth))
    var endX = startX + halfWidth
    
    let path = UIBezierPath()
    path.move(to: CGPoint(x: startX, y: originY))
    path.addLine(to: CGPoint(x: startX, y: bounds.midY))
    
    repeat {
      path.addQuadCurve(
        to: CGPoint(x: endX, y: bounds.midY),
        controlPoint: CGPoint(
          x: startX + quarterWidth,
          y: up ? bounds.maxY + halfHeight : bounds.minY - halfHeight)
      )
      startX = endX
{'fraction_non_alphanumeric': 0.11757596685082873, 'fraction_numerical': 0.012689917127071824, 'mean_word_length': 2.6989144316730522, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5428608', 'n_tokens_mistral': 4117, 'n_tokens_neox': 3897, 'n_words': 983}