//
//  LineDrawing.swift
//  
//  Copyright © 2016-2019 Apple Inc. All rights reserved.
//

import UIKit

public enum CutscenePath: String {
    case cameraImage, imageAlbum, albumOffscreen, saveToPhotos, decorate
}

public var lineStrokeColor = UIColor(red:0.41, green:0.60, blue:0.60, alpha:1.00)

public func createIntroLayer(path: CutscenePath) -> CAShapeLayer {
    let shapeLayer = CAShapeLayer()
    shapeLayer.strokeColor = lineStrokeColor.cgColor
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.lineWidth = 10
    shapeLayer.lineCap = .round
    shapeLayer.lineJoin = .round
    
    switch path {
    case .cameraImage:
        shapeLayer.path = cameraImagePath()
    case .imageAlbum:
        shapeLayer.path = imageAlbumPath()
    case .albumOffscreen:
        shapeLayer.path = albumOffscreenPath()
    case .saveToPhotos:
        shapeLayer.path = saveToPhotosPath()
    case .decorate:
        shapeLayer.path = decoratePath()
    }
    return shapeLayer
}

// Camera to Image view
private func cameraImagePath() -> CGPath {
    let bezierPath = UIBezierPath()
    
    bezierPath.move(to: CGPoint(x: 217, y: 319))
    bezierPath.addQuadCurve(to: CGPoint(x: 277, y: 258), controlPoint: CGPoint(x: 217, y: 258))
    bezierPath.addLine(to: CGPoint(x: 533, y: 258))
    bezierPath.addQuadCurve(to: CGPoint(x: 593, y: 319), controlPoint: CGPoint(x: 593, y: 258))

    return bezierPath.cgPath
}

// Image view to album view
private func imageAlbumPath() -> CGPath {
    let bezierPath = UIBezierPath()
    
    bezierPath.move(to: CGPoint(x: 298, y: 434))
    bezierPath.addLine(to: CGPoint(x: 298, y: 484))
    bezierPath.addQuadCurve(to: CGPoint(x: 343, y: 530), controlPoint: CGPoint(x: 298, y: 530))
    bezierPath.addLine(to: CGPoint(x: 791, y: 530))
    
    return bezierPath.cgPath
}

// Album view to screen edge
private func albumOffscreenPath() -> CGPath {
    let bezierPath = UIBezierPath()
    
    bezierPath.move(to: CGPoint(x: 915, y: 530))
    bezierPath.addLine(to: CGPoint(x: 1024, y: 530))
    
    return bezierPath.cgPath
}

private func saveToPhotosPath() -> CGPath {
    let bezierPath = UIBezierPath()
    
    bezierPath.move(to: CGPoint(x: 0, y: 530))
    bezierPath.addLine(to: CGPoint(x: 222, y: 530))
    bezierPath.addQuadCurve(to: CGPoint(x: 280, y: 492), controlPoint: CGPoint(x: 280, y: 530))
    bezierPath.addLine(to: CGPoint(x: 280, y: 428))
    bezierPath.addQuadCurve(to: CGPoint(x: 319, y: 387), controlPoint: CGPoint(x: 280, y: 387))
    bezierPath.addQuadCurve(to: CGPoint(x: 495, y: 484), controlPoint: CGPoint(x: 423, y: 395))
    bezierPath.addQuadCurve(to: CGPoint(x: 660, y: 548), controlPoint: CGPoint(x: 570, y: 530))
    bezierPath.addQuadCurve(to: CGPoint(x: 715, y: 560), controlPoint: CGPoint(x: 715, y: 550))
    bezierPath.addQuadCurve(to: CGPoint(x: 760, y: 578), controlPoint: CGPoint(x: 725, y: 581))
    bezierPath.addLine(to: CGPoint(x: 1024, y: 578))
    
    return bezierPath.cgPath
}

private func decoratePath() -> CGPath {
    let bezierPath = UIBezierPath()
    
    bezierPath.move(to: CGPoint(x: 0, y: 570))
    bezierPath.addLine(to: CGPoint(x: 140, y: 570))
    bezierPath.addQuadCurve(to: CGPoint(x: 185, y: 525), controlPoint: CGPoint(x: 185, y: 570))
    bezierPath.addLine(to: CGPoint(x: 185, y: 352))
    bezierPath.addQuadCurve(to: CGPoint(x: 225, y: 308), controlPoint: CGPoint(x: 185, y: 308))
    bezierPath.addLine(to: CGPoint(x: 466, y: 308))
    bezierPath.addLine(to: CGPoint(x: 466, y: 68))
    
    bezierPath.addQuadCurve(to: CGPoint(x: 495, y: 40), controlPoint: CGPoint(x: 466, y: 40))
    bezierPath.addQuadCurve(to: CGPoint(x: 524, y: 68), controlPoint: CGPoint(x: 524, y: 40))
    
    bezierPath.addLine(to: CGPoint(x: 524, y: 377))
    bezierPath.addLine(to: CGPoint(x: 681, y: 377))
    bezierPath.addLine(to: CGPoint(x: 681, y: 177))
    
    bezierPath.addQuadCurve(to: CGPoint(x: 710, y: 149), controlPoint: CGPoint(x: 681, y: 149))
    bezierPath.addQuadCurve(to: CGPoint(x: 739, y: 177), controlPoint: CGPoint(x: 739, y: 149))
    
    bezierPath.addLine(to: CGPoint(x: 739, y: 453))
    
    bezierPath.addQuadCurve(to: CGPoint(x: 783, y: 509), controlPoint: CGPoint(x: 739, y: 509))
    
    bezierPath.addLine(to: CGPoint(x: 1024, y: 509))
    
    return bezierPath.cgPath
}

public func sinePath(in rect: CGRect, origin: CGPoint, amplitude: CGFloat, frequency: Double, horizontal: Bool = true) -> CGPath {
    
    let width = rect.width
    let height = rect.height
    
    let bezierPath = UIBezierPath()
    bezierPath.move(to: origin)
    
    for angle in stride(from: 5.0, to: 360.0, by: 5.0) {
        let x: CGFloat
        let y: CGFloat
        if horizontal {
            x = origin.x + CGFloat(angle/360.0) * width
            y = origin.y - CGFloat(sin(angle/180.0 * Double.pi * frequency)) * height * amplitude
        } else {
            y = origin.y + CGFloat(angle/360.0) * height
            x = origin.x - CGFloat(sin(angle/180.0 * Double.pi * frequency)) * width * amplitude
        }
        bezierPath.addLine(to: CGPoint(x: x, y: y))
    }
    
    bezierPath.stroke()
    
    return bezierPath.cgPath
}
