/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class WXSDKInstance;
@class WXLength;

@interface WXTransform : NSObject

@property (nonatomic, assign, readonly) float rotateAngle;
@property (nonatomic, assign, readonly) float rotateX;
@property (nonatomic, assign, readonly) float rotateY;
@property (nonatomic, assign, readonly) float rotateZ;
@property (nonatomic, strong, readonly) WXLength *translateX;
@property (nonatomic, strong, readonly) WXLength *translateY;
@property (nonatomic, assign, readonly) float scaleX;
@property (nonatomic, assign, readonly) float scaleY;
@property (nonatomic, assign) float perspective;

- (instancetype)initWithCSSValue:(NSString *)cssValue origin:(NSString *)origin instance:(WXSDKInstance *)instance;

- (instancetype)initWithNativeTransform:(CATransform3D)transform instance:(WXSDKInstance *)instance;

- (void)applyTransformForView:(UIView *)view;

- (void)setTransformOrigin:(NSString *)transformOriginCSS;

@end
