 import Foundation
 import Cocoa
 
+private let duration = 1.5
+private let strokeRange = (start: 0.0, end: 0.8)
+private let defaultStrokeColor = NSColor.whiteColor()
 private let defaultBackgroundColor = NSColor(calibratedWhite: 0.07, alpha: 0.7)
-private let defaultStrokeColor = NSColor.whiteColor()
 
 @IBDesignable
 class CircularSnail: IndeterminateAnimation {

    var animationGroup: CAAnimationGroup = {
        var tempGroup = CAAnimationGroup()
        tempGroup.repeatCount = 1
        return tempGroup
    }()
    
    var strokeEndAnimation: CABasicAnimation = {
        var tempAnimation = CABasicAnimation(keyPath: "strokeEnd")
        tempAnimation.repeatCount = 1
        tempAnimation.speed = 2.0
        tempAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        tempAnimation.fillMode = kCAFillModeForwards // kCAFillModeBoth
        return tempAnimation
        }()

    var strokeStartAnimation: CABasicAnimation = {
        var tempAnimation = CABasicAnimation(keyPath: "strokeStart")
        tempAnimation.repeatCount = 1
        tempAnimation.speed = 2.0
        tempAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        return tempAnimation
        }()
    
    
    var rotationAnimation: CABasicAnimation = {
        var tempRotation = CABasicAnimation(keyPath: "transform.rotation")

        tempRotation.fromValue = 0
        tempRotation.toValue = 1
        tempRotation.cumulative = true
        tempRotation.duration = duration / 2
        return tempRotation
        }()

    func makeLayers() {
        self.wantsLayer = true
        let rect = self.bounds
        backgroundLayer.cornerRadius = rect.midX
        backgroundLayer.frame = rect
        backgroundLayer.backgroundColor = backgroundColor.CGColor
        self.layer?.addSublayer(backgroundLayer)
        
        // Progress Layer
        let radius = (rect.width / 2) * 0.75
        progressLayer.frame =  rect
        progressLayer.lineWidth = lineWidth == -1 ? radius / 10: lineWidth
        var arcPath = NSBezierPath()
        arcPath.appendBezierPathWithArcWithCenter(rect.mid, radius: radius, startAngle: 0, endAngle: 360, clockwise: false)
        progressLayer.path = arcPath.CGPath
        backgroundLayer.addSublayer(progressLayer)
    }
    
    
    //MARK: Initialization
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        makeStrokeAnimations()
        makeLayers()
    }

    var currentRotation = 0.0
    let π2 = M_PI * 2
    override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {
        if !animate { return }
        CATransaction.begin()
        CATransaction.setDisableActions(true)
        currentRotation += strokeRange.end * π2
        currentRotation %= π2
        progressLayer.setAffineTransform(CGAffineTransformMakeRotation(CGFloat( currentRotation)))
        CATransaction.commit()
        progressLayer.addAnimation(animationGroup, forKey: "strokeEnd")
    }
