         case .RotationX, .RotationY, .RotationZ:
             let angle = frame.values.first! / 180.0 * M_PI
             return angle
+        case .Scale:
+            fatalError("please extract to .ScaleX, .ScaleY, .ScaleZ first.")
         }
     }
 }
    case RotationX
    case RotationY
    case RotationZ
}

struct CurveData {
    let frames : [FrameData]

    public func animation(name:String, ofProperty prop:Property, center: CGPoint) -> CAAnimation? {
        guard let curve = curves[name] else { return nil }
        
        if prop == .Scale {
            let combinedAnim = CAAnimationGroup()
            combinedAnim.animations = [
                keyframeAnimation(curve, prop: .ScaleX, center: center),
                keyframeAnimation(curve, prop: .ScaleY, center: center),
                keyframeAnimation(curve, prop: .ScaleZ, center: center)
            ]
            combinedAnim.duration = (combinedAnim.animations?.first!.duration)!
            return combinedAnim
        } else {
            return keyframeAnimation(curve, prop: prop, center: center)
        }
    }
    
    func keyframeAnimation(curve:CurveData, prop:Property, center:CGPoint) -> CAAnimation {
        var keyPath = "transform"
        switch prop {
        case .ScaleX:
            keyPath = "transform.scale.x"
        case .ScaleY:
            keyPath = "transform.scale.y"
        case .ScaleZ:
            keyPath = "transform.scale.z"
        case .Position:
            keyPath = "position"
        case .RotationX:
            keyPath = "transform.rotation.x"
        case .RotationY:
            keyPath = "transform.rotation.y"
        case .RotationZ:
            keyPath = "transform.rotation.z"
        case .Scale:
            fatalError("please extract to .ScaleX, .ScaleY, .ScaleZ first.")
        }
        
        let startTime = curve.startTime / 1000.0
        let duration = curve.duration / 1000.0
        
        let anim = CAKeyframeAnimation(keyPath: keyPath)
        anim.duration = max(duration + startTime, curve.frames.last!.time / 1000.0)
        anim.cumulative = false
        
        // Add Keypoints
        anim.keyTimes = curve.frames.map { ($0.time / 1000.0) / anim.duration }
        anim.timingFunctions = curve.frames.map { _ in CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) }
        anim.values = curve.frames.map { animationValue($0, curve: curve, prop: prop, center: center) }
        
        // Add Initial delay
        anim.keyTimes?.insert(0, atIndex: 0)
        anim.timingFunctions?.insert(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn), atIndex: 0)
        anim.values?.insert(anim.values!.first!, atIndex: 0)
        return anim
    }
    
    
    func animationValue(frame:FrameData, curve:CurveData, prop:Property, center: CGPoint) ->  AnyObject {
        switch prop {
        case .ScaleX:
            return (frame.values[0] ?? 100.0) / 100.0
        case .ScaleY:
            return (frame.values[1] ?? 100.0) / 100.0
        case .ScaleZ:
            return (frame.values[2] ?? 100.0) / 100.0
        case .Position:
            // Make relative position
            let x = curve.begin[0] - (frame.values[0] ?? 0.0) + Double(center.x)
