     /// Progress animation duration can be adjusted using `CATransaction.setAnimationDuration()`.
     open var progress: Double {
         get {
-            return Double((layer as! MKRingProgressLayer).progress)
-        }
-        set {
-            (layer as! MKRingProgressLayer).progress = CGFloat(newValue)
+            return Double(ringProgressLayer.progress)
+        }
+        set {
+            ringProgressLayer.progress = CGFloat(newValue)
         }
     }
     
     open override class var layerClass: AnyClass {
         return MKRingProgressLayer.self
     }
-    
+        
+    private var ringProgressLayer: MKRingProgressLayer {
+        return layer as! MKRingProgressLayer
+    }
+    
+}
+
+public enum ProgressStyle {
+    case round
+    case square
+}
+
+fileprivate extension ProgressStyle {
+    var lineCap: CGLineCap {
+        switch self {
+        case .round:
+            return .round
+        case .square:
+            return .butt
+        }
+    }
+    var lineJoin: CGLineJoin {
+        switch self {
+        case .round:
+            return .round
+        case .square:
+            return .miter
+        }
+    }
 }
 
 

    open var ringWidth: CGFloat = 20 {
        didSet {
            setNeedsRedrawContents()
        }
    }
    

        let shadowOffset = CGSize(width: w/10 * cos(angle + angleOffset), height: w/10 * sin(angle + angleOffset))
        ctx.setShadow(offset: shadowOffset, blur: w/3, color: UIColor(white: 0.0, alpha: endShadowOpacity).cgColor)
        let arcEnd = CGPoint(x: c.x + r * cos(angle1), y: c.y + r * sin(angle1))
        
        let shadowPath: UIBezierPath
        
        switch progressStyle {
        case .round:
            shadowPath = UIBezierPath(ovalIn: CGRect(x: arcEnd.x - w/2, y: arcEnd.y - w/2, width: w, height: w))
        case .square:
            shadowPath = UIBezierPath(rect: CGRect(x: arcEnd.x - w/2, y: arcEnd.y - 2, width: w, height: 2))
            shadowPath.apply(CGAffineTransform(translationX: -arcEnd.x, y: -arcEnd.y))
            shadowPath.apply(CGAffineTransform(rotationAngle: angle1))
            shadowPath.apply(CGAffineTransform(translationX: arcEnd.x, y: arcEnd.y))
        }
        
        ctx.addPath(shadowPath.cgPath)
        ctx.setFillColor(endColor)
        ctx.fillPath()
        
        ctx.restoreGState()
