//
//  Shape.swift
//  SPCScene
//
//  Created by Marcus Jackson on 3/5/20.
//  Copyright © 2020 Apple Computer. All rights reserved.
//

import Foundation
import SPCCore

import UIKit


public enum Shape {
    case circle(radius: Int)
    case rectangle(width: Int, height: Int, cornerRadius: Double)
    case polygon(radius: Int, sides: Int)
    case star(radius: Int, points: Int, sharpness: Double)
}

/// An enumeration of the types of basic shapes, including: circle, rectangle, polygon, and star.
///
/// - localizationKey: BasicShape
public enum BasicShape {
    case circle(radius: Int, color: Color, gradientColor: Color)
    case rectangle(width: Int, height: Int, cornerRadius: Double, color: Color, gradientColor: Color)
    case polygon(radius: Int, sides: Int, color: Color, gradientColor: Color)
    case star(radius: Int, points: Int, sharpness: Double, color: Color, gradientColor: Color)
    
    public var size: CGSize {
        switch self {
        case .circle(let attr):
            return CGSize(width: attr.radius * 2, height: attr.radius * 2)
        case .rectangle(let attr):
            return CGSize(width: attr.width, height: attr.height)
        case .polygon(let attr):
            return CGSize(width: attr.radius * 2, height: attr.radius * 2)
        case .star(let attr):
            return CGSize(width: attr.radius * 2, height: attr.radius * 2)
        }
    }
    
    private var color: Color {
        switch self {
        case .circle(let attr):
            return attr.color
        case .rectangle(let attr):
            return attr.color
        case .polygon(let attr):
            return attr.color
        case .star(let attr):
            return attr.color
        }
    }
    
    private var gradientColor: Color {
        switch self {
        case .circle(let attr):
            return attr.gradientColor
        case .rectangle(let attr):
            return attr.gradientColor
        case .polygon(let attr):
            return attr.gradientColor
        case .star(let attr):
            return attr.gradientColor
        }
    }
    
    private var path: CGPath {
        let origin = CGPoint(x: 0, y: 0)
        switch self {
        case .circle:
            return UIBezierPath(ovalIn: CGRect(origin: origin, size: size)).cgPath
        case .rectangle(let attr):
            return UIBezierPath(roundedRect: CGRect(origin: origin, size: size), cornerRadius: CGFloat(attr.cornerRadius)).cgPath
        case .polygon(let attr):
            return UIBezierPath(polygonIn: CGRect(origin: origin, size: size), sides: attr.sides).cgPath
        case .star(let attr):
            return UIBezierPath(starIn: CGRect(origin: origin, size: size), points: attr.points, sharpness: CGFloat(attr.sharpness)).cgPath
        }
    }
    
    var image: UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        let ctx = UIGraphicsGetCurrentContext()!
        ctx.saveGState()
        
        ctx.beginPath()
        ctx.addPath(path)
        ctx.clip()
        
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let colors = [color.cgColor, gradientColor.cgColor] as CFArray
        
        let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: nil)!
        ctx.drawLinearGradient(gradient, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 0, y: size.height), options: [])
        
        ctx.restoreGState()
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return img ?? UIImage()
    }
    
    enum ShapeType: String, RawRepresentable {
        case circle
        case rectangle
        case polygon
        case star
    }
    
    var type: ShapeType {
        switch self {
        case .circle:
            return .circle
        case .polygon:
            return .polygon
        case .rectangle:
            return .rectangle
        case .star:
            return .star
        }
    }
}

/// An enumeration of the types of basic shapes, including: circle, rectangle, polygon and star.
///
/// - localizationKey: Shape
public enum ShapeType {
    case circle(radius: Int)
    case rectangle(width: Int, height: Int, cornerRadius: Double)
    case polygon(radius: Int, sides: Int)
    case star(radius: Int, points: Int, sharpness: Double)
}

extension UIBezierPath
{
    public convenience init(starIn rect: CGRect, points: Int, sharpness: CGFloat = 1.4) {
        let midpoint = CGPoint(x: rect.midX, y: rect.midY)
        let radius = min(rect.width, rect.height) / 2 / sharpness
        let path = CGPath.starPath(center: midpoint, radius: radius, numberOfPoints: points, sharpness: sharpness)
        self.init(cgPath: path)
    }
    
    public convenience init(polygonIn rect: CGRect, sides: Int) {
        let midpoint = CGPoint(x: rect.midX, y: rect.midY)
        let radius = min(rect.width, rect.height) / 2
        let path = CGPath.polygonPath(center: midpoint, radius: radius, sides: sides)
        self.init(cgPath: path)
    }
}
