/*
 * 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 "WXTransform.h"
#import "math.h"
#import "WXLength.h"
#import "WXUtility.h"
#import "WXSDKInstance.h"
#import "WXConvert.h"
#import "WXSDKEngine.h"
#import "WXConfigCenterProtocol.h"

@interface WXTransform()

@property (nonatomic, weak) WXSDKInstance *weexInstance;

@end

@implementation WXTransform
{
    float _rotateAngle; //for rotate
    float _scaleX;
    float _scaleY;
    WXLength *_translateX;
    WXLength *_translateY;
    WXLength *_originX;
    WXLength *_originY;
    
    //3d rotate
    float _rotateX;
    float _rotateY;
    float _rotateZ;
    float _perspective;
    
    CATransform3D _nativeTransform;
    BOOL _useNativeTransform;
}

- (instancetype)initWithCSSValue:(NSString *)cssValue origin:(NSString *)origin instance:(WXSDKInstance *)instance
{
    if (self = [super init]) {
        _weexInstance = instance;
        _scaleX = 1.0;
        _scaleY = 1.0;
        _rotateX = 0.0;
        _rotateY = 0.0;
        _rotateZ = 0.0;
        _rotateAngle = 0.0;
        
        // default is parallel projection
        _perspective = CGFLOAT_MAX;
        
        [self parseTransform:cssValue];
        [self parseTransformOrigin:origin];
    }
    
    return self;
}

- (instancetype)initWithNativeTransform:(CATransform3D)transform instance:(WXSDKInstance *)instance
{
    if (self = [super init]) {
        _weexInstance = instance;
        _nativeTransform = transform;
        _useNativeTransform = YES;
    }
    return self;
}

- (float)rotateAngle
{
    if (_useNativeTransform) {
        return atan2(_nativeTransform.m11, _nativeTransform.m12);
    }
    return _rotateAngle;
}

- (float)rotateX
{
    if (_useNativeTransform) {
        return atan2(_nativeTransform.m22, _nativeTransform.m23);
    }
    return _rotateX;
}

- (float)rotateY
{
    if (_useNativeTransform) {
        return atan2(_nativeTransform.m11, _nativeTransform.m31);
    }
    return _rotateY;
}

- (float)rotateZ
{
    return _rotateZ;
}

- (WXLength *)translateX
{
    if (_useNativeTransform) {
        return [WXLength lengthWithFloat:_nativeTransform.m41 type:WXLengthTypeFixed];
    }
    return _translateX;
}

- (WXLength *)translateY
{
    if (_useNativeTransform) {
        return [WXLength lengthWithFloat:_nativeTransform.m42 type:WXLengthTypeFixed];
    }
    return _translateY;
}

- (float)scaleX
{
    if (_useNativeTransform) {
        return sqrt(_nativeTransform.m11 * _nativeTransform.m11 + _nativeTransform.m21 * _nativeTransform.m21);
    }
    return _scaleX;
}

- (float)scaleY
{
    if (_useNativeTransform) {
        return sqrt(_nativeTransform.m12 * _nativeTransform.m12 + _nativeTransform.m22 * _nativeTransform.m22);
    }
    return _scaleY;
}

- (void)setTransformOrigin:(NSString *)transformOriginCSS
{
    [self parseTransformOrigin:transformOriginCSS];
}

- (CATransform3D)nativeTransformWithView:(UIView *)view
{
    if (_useNativeTransform) {
        return _nativeTransform;
    }
    
    CATransform3D nativeTransform3d = [self nativeTransformWithoutRotateWithView:view];

    if (_rotateAngle != 0 || _rotateZ != 0) {
        nativeTransform3d = CATransform3DRotate(nativeTransform3d, _rotateAngle?:_rotateZ, 0, 0, 1);
    }
    
    if (_rotateY != 0) {
        nativeTransform3d = CATransform3DRotate(nativeTransform3d, _rotateY, 0, 1, 0);
    }
    
    if (_rotateX != 0) {
        nativeTransform3d = CATransform3DRotate(nativeTransform3d, _rotateX, 1, 0, 0);
    }
    
    return nativeTransform3d;
}

- (CATransform3D)nativeTransformWithoutRotateWithView:(UIView *)view
{
    CATransform3D nativeTansform3D = CATransform3DIdentity;
    
    // CGFLOAT_MAX is not INF on 32-bit device
    if(_perspective && _perspective != CGFLOAT_MAX && !isinf(_perspective)) {
        nativeTansform3D.m34 = -1.0/_perspective;
    }
    if (!view || view.bounds.size.width <= 0 || view.bounds.size.height <= 0) {
        return nativeTansform3D;
    }
    
    if (_translateX || _translateY) {
        
        nativeTansform3D = CATransform3DTranslate(nativeTansform3D, _translateX ? [_translateX valueForMaximum:view.bounds.size.width] : 0, _translateY ? [_translateY valueForMaximum:view.bounds.size.height]:0, 0);
    }
    nativeTansform3D = CATransform3DScale(nativeTansform3D, _scaleX, _scaleY, 1.0);
    
    return nativeTansform3D;
}

-(void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view
{
    CGPoint newPoint = CGPointMake(view.bounds.size.width * anchorPoint.x,
                                   view.bounds.size.height * anchorPoint.y);
    CGPoint oldPoint = CGPointMake(view.bounds.size.width * view.layer.anchorPoint.x,
                                   view.bounds.size.height * view.layer.anchorPoint.y);
    
    newPoint = CGPointApplyAffineTransform(newPoint, view.transform);
    oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform);
    
    CGPoint position = view.layer.position;
    
    position.x -= oldPoint.x;
    position.x += newPoint.x;
    
    position.y -= oldPoint.y;
    position.y += newPoint.y;
    
    view.layer.position = position;
    view.layer.anchorPoint = anchorPoint;
}


- (void)applyTransformForView:(UIView *)view
{
    if (!view || view.bounds.size.width <= 0 || view.bounds.size.height <= 0) {
        return;
    }
    
    BOOL applyTransformOrigin = _originX || _originY;
    if (applyTransformOrigin) {
        /**
          * Waiting to fix the issue that transform-origin behaves in rotation
          * http://ronnqvi.st/translate-rotate-translate/
          **/
        CGPoint anchorPoint = CGPointMake(
                                          _originX ? [_originX valueForMaximum:view.bounds.size.width] / view.bounds.size.width : 0.5,
                                          _originY ? [_originY valueForMaximum:view.bounds.size.height] / view.bounds.size.height : 0.5);
        [self setAnchorPoint:anchorPoint forView:view];
    }
    CATransform3D nativeTransform3d = [self nativeTransformWithView:view];
    if (!CATransform3DEqualToTransform(view.layer.transform, nativeTransform3d)){
        view.layer.transform = nativeTransform3d;
    }
}

- (void)parseTransform:(NSString *)cssValue
{
    if (!cssValue || cssValue.length == 0 || [cssValue isEqualToString:@"none"]) {
        return;
    }
    
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\w+)\\((.+?)\\)"
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];
    
    NSArray *matches = [regex matchesInString:cssValue options:0 range:NSMakeRange(0, cssValue.length)];
    
    for (NSTextCheckingResult *match in matches) {
        NSString *name = [cssValue substringWithRange:[match rangeAtIndex:1]];
        NSArray *value = [[cssValue substringWithRange:[match rangeAtIndex:2]] componentsSeparatedByString:@","];
        
        SEL method = NSSelectorFromString([NSString stringWithFormat:@"parse%@:", [name capitalizedString]]);
        if ([self respondsToSelector:method]) {
            @try {
                id<WXConfigCenterProtocol> configCenter = [WXSDKEngine handlerForProtocol:@protocol(WXConfigCenterProtocol)];
                if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
                    BOOL parseTransformIfWaitUntilDone = [[configCenter configForKey:@"iOS_weex_ext_config.parseTransformIfWaitUntilDone" defaultValue:@(NO) isDefault:NULL] boolValue];
                    if (parseTransformIfWaitUntilDone) {
                        [self performSelectorOnMainThread:method withObject:value waitUntilDone:YES];
                    }
                    else{
                        IMP imp = [self methodForSelector:method];
                        void (*func)(id, SEL,NSArray *) = (void *)imp;
                        func(self, method,value);
                    }
                }
            }
            @catch (NSException *exception) {
                WXLogError(@"WXTransform exception:%@", [exception reason]);
            }
        }
    }
}

- (void)parseTransformOrigin:(NSString *)cssValue
{
    if (!cssValue || cssValue.length == 0 || [cssValue isEqualToString:@"none"]) {
        return;
    }
    
    NSArray *values = [cssValue componentsSeparatedByString:@" "];

    double originX = 50;
    double originY = 50;
    WXLengthType typeX = WXLengthTypePercent;
    WXLengthType typeY = WXLengthTypePercent;
    for (NSInteger i = 0; i < values.count; i++) {
        NSString *value = values[i];
        if ([value isEqualToString:@"left"]) {
            originX = 0;
        } else if ([value isEqualToString:@"right"]) {
            originX = 100;
        } else if ([value isEqualToString:@"top"]) {
            originY = 0;
        } else if ([value isEqualToString:@"bottom"]) {
            originY = 100;
        } else if ([value isEqualToString:@"center"]) {
            if (i == 0) {
                originX = 50;
            } else {
                originY = 50;
            }
        } else {
            double val = [value doubleValue];
            if (i == 0) {
                if ([value hasSuffix:@"%"]) {
                    originX = val;
                } else {
                    typeX = WXLengthTypeFixed;
                    originX = WXPixelScale(val, self.weexInstance.pixelScaleFactor);
                }
            } else {
                if ([value hasSuffix:@"%"]) {
                    originY = val;
                } else {
                    typeY = WXLengthTypeFixed;
                    originY = WXPixelScale(val, self.weexInstance.pixelScaleFactor);
                }
            }
        }
    }
    _originX = [WXLength lengthWithFloat:originX type:typeX];
    _originY = [WXLength lengthWithFloat:originY type:typeY];
}

- (void)parseRotate:(NSArray *)value
{
    float rotateAngle = [self getAngle:value[0]];
    _rotateAngle = rotateAngle;
}

- (void)parseRotatex:(NSArray *)value
{
    _rotateX = [self getAngle:value[0]];
}

- (void)parseRotatey:(NSArray *)value
{
    _rotateY = [self getAngle:value[0]];
}

- (void)parseRotatez:(NSArray *)value
{
   _rotateZ = [self getAngle:value[0]];
}

- (void)parsePerspective:(NSArray *)value
{
    _perspective = [WXConvert WXPixelType:value[0] scaleFactor:self.weexInstance.pixelScaleFactor];
    if (_perspective <= 0 ) {
        _perspective = CGFLOAT_MAX;
    }
}

- (void)parseTranslate:(NSArray *)value
{
    [self parseTranslatex:@[value[0]]];
    if (value.count > 1) {
        [self parseTranslatey:@[value[1]]];
    }
}

- (void)parseTranslatex:(NSArray *)value
{
    WXLength *translateX;
    double x = [value[0] doubleValue];
    if ([value[0] hasSuffix:@"%"]) {
        translateX = [WXLength lengthWithFloat:x type:WXLengthTypePercent];
    } else {
        x = WXPixelScale(x, self.weexInstance.pixelScaleFactor);
        translateX = [WXLength lengthWithFloat:x type:WXLengthTypeFixed];
    }
    _translateX = translateX;
}

- (void)parseTranslatey:(NSArray *)value
{
    WXLength *translateY;
    double y = [value[0] doubleValue];
    if ([value[0] hasSuffix:@"%"]) {
        translateY = [WXLength lengthWithFloat:y type:WXLengthTypePercent];
    } else {
        y = WXPixelScale(y, self.weexInstance.pixelScaleFactor);
        translateY = [WXLength lengthWithFloat:y type:WXLengthTypeFixed];
    }
    _translateY = translateY;
}

- (void)parseScale:(NSArray *)value
{
    double x = [value[0] doubleValue];
    double y = x;
    if (value.count == 2) {
        y = [value[1] doubleValue];
    }
    _scaleX = x;
    _scaleY = y;
}

- (void)parseScalex:(NSArray *)value
{
    [self parseScale:@[value[0], @1]];
}

- (void)parseScaley:(NSArray *)value
{
    [self parseScale:@[@1, value[0]]];
}

// Angle in radians
- (double)getAngle:(NSString *)value
{
    double angle = [value doubleValue];
    if ([value hasSuffix:@"deg"]) {
        return [self deg2rad:angle];
    } else {
        return angle;
    }
}

- (double)deg2rad:(double)deg
{
    return deg * M_PI / 180.0;
}

@end
