/*
 * 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.
 */

#define SOLVE_EPS(dur) (1. / (1000. * (dur)))

#import <QuartzCore/CATransaction.h>
#import <QuartzCore/CADisplayLink.h>
#import "WXComponentManager.h"
#import "WXSDKInstance.h"
#import "WXComponent+Layout.h"
#import "WXComponent_internal.h"
#import "WXTransition.h"
#import "WXUtility.h"
#import "WXAssert.h"
#import "WXSDKInstance_private.h"
#import "WXLength.h"

@implementation WXTransitionInfo
@end

@interface WXTransition()
{
    double ax;
    double bx;
    double cx;
    
    double ay;
    double by;
    double cy;
    
    float _transitionDuration;
    float _transitionDelay;
    NSUInteger _transitionCount;
    
    CAMediaTimingFunction *_transitionTimingFunction;
    CADisplayLink *_transitionDisplayLink;

    NSMutableDictionary *_filterStyles;
    NSMutableDictionary *_oldFilterStyles;
}
@property (nonatomic,weak) WXComponent *targetComponent;
@end

@implementation WXTransition

- (instancetype)initWithStyles:(NSDictionary *)styles
{
    if (self = [super init]) {
        NSString *property = styles[kWXTransitionProperty];
        NSArray *properties = [property componentsSeparatedByString:@","];
        for (NSString *string in properties) {
            _transitionOptions |= [self transitionOptionsFromString:string];
        }
    }
    return self;
}

#pragma mark - HandleStyle
- (WXTransitionOptions)transitionOptionsFromString:(NSString *)string
{
    static NSDictionary<NSString*, NSNumber*> *options = @{
                                                           @"width": @(WXTransitionOptionsWidth),
                                                           @"height": @(WXTransitionOptionsHeight),
                                                           @"right": @(WXTransitionOptionsRight),
                                                           @"left": @(WXTransitionOptionsLeft),
                                                           @"bottom": @(WXTransitionOptionsBottom),
                                                           @"top": @(WXTransitionOptionsTop),
                                                           @"backgroundColor": @(WXTransitionOptionsBackgroundColor),
                                                           @"transform": @(WXTransitionOptionsTransform),
                                                           @"opacity": @(WXTransitionOptionsOpacity)
                                                           };
    return options[string].integerValue;
}

- (void)_handleTransitionWithStyles:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles target:(WXComponent *)targetComponent
{
    BOOL isRunning = [self _isTransitionRunning];
    if (isRunning) {
        [self _rollBackTransitionWithStyles:styles];
    }
    else
    {
        [self _suspendTransitionDisplayLink];
    }
    
    if (!targetComponent) {
        return;
    }
    
    _filterStyles = _filterStyles ?:[NSMutableDictionary new];
    _oldFilterStyles = _oldFilterStyles ?: [NSMutableDictionary new];
    NSMutableDictionary *futileStyles = [NSMutableDictionary new];
    
    for (NSString *key in styles) {
        if (self.transitionOptions & [self transitionOptionsFromString:key]) {
            [_filterStyles setObject:styles[key] forKey:key];
            if (![key isEqualToString:@"transform"]) {
                if (!isRunning) {
                    /* style value may not be in component.styles, so we must get
                     value from layout and convert it to style value. */
                    id styleValue = targetComponent.styles[key];
                    if (styleValue == nil) {
                        styleValue = [targetComponent convertLayoutValueToStyleValue:key];
                    }
                    [_oldFilterStyles setObject:styleValue forKey:key];
                }
            }
        }
        else
        {
            [futileStyles setObject:styles[key] forKey:key];
        }
    }
    [self updateFutileStyles:futileStyles resetStyles:nil target:targetComponent];

    _targetComponent = targetComponent;
    NSMutableDictionary *componentStyles = [NSMutableDictionary dictionaryWithDictionary:styles];
    [componentStyles addEntriesFromDictionary:targetComponent.styles];

    _transitionDuration = componentStyles[kWXTransitionDuration] ? [WXConvert CGFloat:componentStyles[kWXTransitionDuration]] : 0;
    _transitionDelay = componentStyles[kWXTransitionDelay] ? [WXConvert CGFloat:componentStyles[kWXTransitionDelay]] : 0;
    _transitionTimingFunction = [WXConvert CAMediaTimingFunction:componentStyles[kWXTransitionTimingFunction]];
    
    if (_transitionDuration == 0 ) {
        [self updateFutileStyles:_filterStyles resetStyles:nil target:targetComponent];
        return;
    }
    
    if (![[NSString stringWithFormat:@"%@",_transitionTimingFunction] isEqualToString: kCAMediaTimingFunctionLinear]) {
        float vec[4] = {0.};
        [_transitionTimingFunction getControlPointAtIndex:1 values:&vec[0]];
        [_transitionTimingFunction getControlPointAtIndex:2 values:&vec[2]];
        [self unitBezierp1x:vec[0] p1y:vec[1] p2x:vec[2] p2y:vec[3]];
    }
    
    [self _resloveTransitionProperty];
    [self performSelector:@selector(_startTransitionDisplayLink) withObject:self afterDelay:_transitionDelay/1000];
}

- (BOOL)_hasTransitionOptionInStyles:(NSDictionary *)styles
{
    for (NSString *key in styles) {
        if (self.transitionOptions & [self transitionOptionsFromString:key]) {
            return YES;
        }
    }
    return NO;
}

- (void)updateFutileStyles:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles target:(WXComponent *)targetComponent
{
    if (!targetComponent) {
        return;
    }
    [targetComponent _updateCSSNodeStyles:styles];
    [targetComponent _resetCSSNodeStyles:resetStyles];
    NSDictionary* dupStyles = [NSDictionary dictionaryWithDictionary:styles];
    WXPerformBlockOnMainThread(^{
        [targetComponent _updateViewStyles:dupStyles];
    });
}

- (void)_rollBackTransitionWithStyles:(NSDictionary *)styles
{
    _transitionDuration = _transitionCount * 1000 / 60;
    _transitionCount = 0;
    _propertyArray = nil;
}

- (void)_resloveTransitionProperty
{
    if (_filterStyles.count == 0) {
        return;
    }
    for (NSString * name  in _filterStyles.allKeys) {
        [self _dealTransitionWithProperty:name];
    }
}

- (void)_dealTransitionWithProperty:(NSString *)singleProperty
{
    if (_filterStyles[singleProperty])
    {
        if (!_propertyArray) {
            _propertyArray = [NSMutableArray new];
        }
        if ([singleProperty isEqualToString:@"backgroundColor"]) {
            WXTransitionInfo *info = [WXTransitionInfo new];
            info.fromValue = [self _dealWithColor:[WXConvert UIColor:_oldFilterStyles[singleProperty]]];
            info.toValue = [self _dealWithColor:[WXConvert UIColor:_filterStyles[singleProperty]]];
            info.perValue = [self _calculatePerColorRGB1:info.toValue RGB2:info.fromValue];
            info.propertyName = singleProperty;
            [_propertyArray addObject:info];
        }
        else if ([singleProperty isEqualToString:@"transform"]) {
            NSString *transformOrigin = _filterStyles[@"transformOrigin"];
            WXTransform *wxTransform = [[WXTransform alloc] initWithCSSValue:_filterStyles[singleProperty] origin:transformOrigin instance:_targetComponent.weexInstance];
            WXTransform *oldTransform = _targetComponent?_targetComponent->_transform:wxTransform;
            if (wxTransform.rotateAngle != oldTransform.rotateAngle) {
                WXTransitionInfo *info = [WXTransitionInfo new];
                info.propertyName = @"transform.rotation";
                info.fromValue = @(oldTransform.rotateAngle);
                info.toValue = [NSNumber numberWithDouble:wxTransform.rotateAngle];
                info.perValue = @([info.toValue doubleValue] - [info.fromValue doubleValue]);
                [_propertyArray addObject:info];
            }
            if (wxTransform.rotateX != oldTransform.rotateX)
            {
                WXTransitionInfo *info = [WXTransitionInfo new];
                info.propertyName = @"transform.rotation.x";
                info.fromValue = @(oldTransform.rotateX);
                info.toValue = [NSNumber numberWithDouble:wxTransform.rotateX];
                info.perValue = @([info.toValue doubleValue] - [info.fromValue doubleValue]);
                [_propertyArray addObject:info];
            }
            if (wxTransform.rotateY != oldTransform.rotateY)
            {
                WXTransitionInfo *info = [WXTransitionInfo new];
                info.propertyName = @"transform.rotation.y";
                info.fromValue = @(oldTransform.rotateY);
                info.toValue = [NSNumber numberWithDouble:wxTransform.rotateY];
                info.perValue = @([info.toValue doubleValue] - [info.fromValue doubleValue]);
                [_propertyArray addObject:info];
            }
            if (wxTransform.rotateZ != oldTransform.rotateZ)
            {
                WXTransitionInfo *info = [WXTransitionInfo new];
                info.propertyName = @"transform.rotation.z";
                info.fromValue = @(oldTransform.rotateZ);
                info.toValue = [NSNumber numberWithDouble:wxTransform.rotateZ];
                info.perValue = @([info.toValue doubleValue] - [info.fromValue doubleValue]);
                [_propertyArray addObject:info];
            }
            if (wxTransform.scaleX != oldTransform.scaleX) {
                WXTransitionInfo *info = [WXTransitionInfo new];
                info.propertyName = @"transform.scale.x";
                info.fromValue = @(oldTransform.scaleX);
                info.toValue = @(wxTransform.scaleX);
                info.perValue = @([info.toValue doubleValue] - [info.fromValue doubleValue]);
                [_propertyArray addObject:info];
            }
            if (wxTransform.scaleY != oldTransform.scaleY) {
                WXTransitionInfo *info = [WXTransitionInfo new];
                info.propertyName = @"transform.scale.y";
                info.fromValue = @(oldTransform.scaleY);
                info.toValue = @(wxTransform.scaleY);
                info.perValue = @([info.toValue doubleValue] - [info.fromValue doubleValue]);
                [_propertyArray addObject:info];
            }
            if (wxTransform.translateX && [wxTransform.translateX floatValue] !=[oldTransform.translateX floatValue]) {
                WXTransitionInfo *info = [WXTransitionInfo new];
                info.propertyName = @"transform.translation.x";
                info.fromValue = @([oldTransform.translateX floatValue]);
                info.toValue = @([wxTransform.translateX floatValue]);
                info.perValue = @([wxTransform.translateX floatValue] - [oldTransform.translateX floatValue]);
                [_propertyArray addObject:info];
            }
            if (wxTransform.translateY && [wxTransform.translateY floatValue] !=[oldTransform.translateY floatValue]) {
                WXTransitionInfo *info = [WXTransitionInfo new];
                info.propertyName = @"transform.translation.y";
                info.fromValue = @([oldTransform.translateY floatValue]);
                info.toValue = @([wxTransform.translateY floatValue]);
                info.perValue = @([wxTransform.translateY floatValue] - [oldTransform.translateY floatValue]);
                [_propertyArray addObject:info];
            }
            _targetComponent.transform = wxTransform;
        }
        else
        {
            WXTransitionInfo *info = [WXTransitionInfo new];
            info.fromValue = @(_oldFilterStyles[singleProperty] ? [WXConvert CGFloat:_oldFilterStyles[singleProperty]] : 0);
            info.toValue = @(_filterStyles[singleProperty] ? [WXConvert CGFloat:_filterStyles[singleProperty]] : 0 );
            info.perValue = @([info.toValue doubleValue] - [info.fromValue doubleValue]);
            info.propertyName = singleProperty;
            [_propertyArray addObject:info];
        }
    }
}

- (NSArray *)_dealWithColor:(UIColor *)color
{
    CGFloat R, G, B, A;
    [color getRed:&R green:&G blue:&B alpha:&A];
    return @[@(R),@(G),@(B),@(A)];
}

- (NSArray *)_calculatePerColorRGB1:(NSArray *)RGB1 RGB2:(NSArray *)RGB2
{
    CGFloat R = [RGB1[0] doubleValue] - [RGB2[0] doubleValue];
    CGFloat G = [RGB1[1] doubleValue] - [RGB2[1] doubleValue];
    CGFloat B = [RGB1[2] doubleValue] - [RGB2[2] doubleValue];
    CGFloat A = [RGB1[3] doubleValue] - [RGB2[3] doubleValue];
    return @[@(R),@(G),@(B),@(A)];
}

- (void)_calculatetransitionProcessingStyle
{
    if (_targetComponent == nil) {
        return;
    }
    
    if (_propertyArray.count == 0) {
        return;
    }

    // Bugfix: https://github.com/apache/incubator-weex/issues/2347
    NSUInteger frameCount = MAX(_transitionDuration * 60 / 1000, 1);
    NSUInteger currentFrame = _transitionCount + 1;
    double per = (double)currentFrame / frameCount; //linear
    if (currentFrame < frameCount && ![[NSString stringWithFormat:@"%@",_transitionTimingFunction] isEqualToString: kCAMediaTimingFunctionLinear]) {
        per = [self solveWithx:per epsilon:SOLVE_EPS(_transitionDuration)];
    }

    NSString *transformString = [NSString string];
    for (WXTransitionInfo *info in _propertyArray) {
        if ([info.propertyName isEqualToString:@"backgroundColor"]) {
            NSArray *array = @[
                               @([info.fromValue[0] floatValue] + [info.perValue[0] floatValue] * per),
                               @([info.fromValue[1] floatValue] + [info.perValue[1] floatValue] * per),
                               @([info.fromValue[2] floatValue] + [info.perValue[2] floatValue] * per),
                               @([info.fromValue[3] floatValue] + [info.perValue[3] floatValue] * per)];
            UIColor *color = [UIColor colorWithRed:[array[0] floatValue] green:[array[1] floatValue] blue:[array[2] floatValue] alpha:[array[3] floatValue]];
            WXPerformBlockOnMainThread(^{
                _targetComponent.view.backgroundColor = color;
                [_targetComponent.view setNeedsDisplay];
            });
            NSString *colorString = [WXConvert HexWithColor:color];
            [_oldFilterStyles setObject:colorString forKey:info.propertyName];
        }
        else if ([info.propertyName hasPrefix:@"transform"])
        {
            double currentValue = [info.fromValue doubleValue] + [info.perValue doubleValue] * per;
            NSString *newString = [NSString string];
            if ([info.propertyName isEqualToString:@"transform.rotation"]) {
                newString = [NSString stringWithFormat:@"rotate(%lfdeg)",currentValue * 180.0 / M_PI];
                transformString = [transformString stringByAppendingFormat:@" %@",newString];
            }
            if ([info.propertyName isEqualToString:@"transform.rotation.x"]) {
                newString = [NSString stringWithFormat:@"rotateX(%lfdeg)",currentValue * 180.0 / M_PI];
                transformString = [transformString stringByAppendingFormat:@" %@",newString];
            }
            if ([info.propertyName isEqualToString:@"transform.rotation.y"]) {
                newString = [NSString stringWithFormat:@"rotateY(%lfdeg)",currentValue * 180.0 / M_PI];
                transformString = [transformString stringByAppendingFormat:@" %@",newString];
            }
            if ([info.propertyName isEqualToString:@"transform.rotation.z"]) {
                newString = [NSString stringWithFormat:@"rotateZ(%lfdeg)",currentValue * 180.0 / M_PI];
                transformString = [transformString stringByAppendingFormat:@" %@",newString];
            }
            if ([info.propertyName isEqualToString:@"transform.scale.x"]) {
                newString = [NSString stringWithFormat:@"scaleX(%lf)",currentValue];
                transformString = [transformString stringByAppendingFormat:@" %@",newString];
            }
            if ([info.propertyName isEqualToString:@"transform.scale.y"]) {
                newString = [NSString stringWithFormat:@"scaleY(%lf)",currentValue];
                transformString = [transformString stringByAppendingFormat:@" %@",newString];
            }
            if ([info.propertyName isEqualToString:@"transform.translation.x"]) {
                newString = [NSString stringWithFormat:@"translateX(%lfpx)",currentValue / (_targetComponent.weexInstance.pixelScaleFactor?_targetComponent.weexInstance.pixelScaleFactor:[WXUtility defaultPixelScaleFactor])];
                transformString = [transformString stringByAppendingFormat:@" %@",newString];
            }
            if ([info.propertyName isEqualToString:@"transform.translation.y"]) {
                newString = [NSString stringWithFormat:@"translateY(%lfpx)",currentValue / (_targetComponent.weexInstance.pixelScaleFactor?_targetComponent.weexInstance.pixelScaleFactor:[WXUtility defaultPixelScaleFactor])];
                transformString = [transformString stringByAppendingFormat:@" %@",newString];
            }
            [_oldFilterStyles setObject:transformString forKey:@"transform"];
        }
        else
        {
            double currentValue = [info.fromValue doubleValue] + [info.perValue doubleValue] * per;
            [_oldFilterStyles setObject:@(currentValue) forKey:info.propertyName];
        }
    }
    
    /* _oldFilterStyles could be modified in current thread while _updateViewStyles uses it in main thread.
     This may lead to crash in _updateViewStyles because the dictionary items may be retained or
     released multiple times by code like styles[@"transform"]. So we copy _oldFilterStyles and use a duplicate.*/
    NSDictionary* dupStyles = [NSDictionary dictionaryWithDictionary:_oldFilterStyles];
    WXPerformBlockOnMainThread(^{
        [_targetComponent _updateViewStyles:dupStyles];
    });
    [_targetComponent _updateCSSNodeStyles:_oldFilterStyles];
    [_targetComponent.weexInstance.componentManager startComponentTasks];
}

#pragma mark CADisplayLink
- (void)_startTransitionDisplayLink
{
    WXAssertComponentThread();
    if (!_transitionDisplayLink) {
        _transitionDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_handleTransitionDisplayLink)];
        [_transitionDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    }
    else{
        [self _awakeTransitionDisplayLink];
    }
}

- (void)_stopTransitionDisplayLink
{
    WXAssertComponentThread();
    if (_transitionDisplayLink) {
        [_transitionDisplayLink invalidate];
        _transitionDisplayLink = nil;
    }
}

- (BOOL)_isTransitionRunning
{
    WXAssertComponentThread();
    BOOL yesOrNo = NO;
    if (!_transitionDisplayLink.paused && _transitionCount >= 5) {
        yesOrNo = YES;
    }
    return yesOrNo;
}

- (void)_suspendTransitionDisplayLink
{
    WXAssertComponentThread();
    if(_transitionDisplayLink && !_transitionDisplayLink.paused){
        _transitionDisplayLink.paused = YES;
    }
}

- (void)_awakeTransitionDisplayLink
{
    WXAssertComponentThread();
    if (_transitionDisplayLink && _transitionDisplayLink.paused) {
        _transitionDisplayLink.paused = NO;
    }
}

- (void)_handleTransitionDisplayLink
{
    WXAssertComponentThread();
    int count = MAX(_transitionDuration * 60 / 1000, 1);
    if (_transitionCount >= count) {
        [self _suspendTransitionDisplayLink];
        [self _resetProcessAnimationParameter];
        return;
    }
    else
    {
        [self _calculatetransitionProcessingStyle];
    }
    _transitionCount ++;
}

- (void)_resetProcessAnimationParameter
{
    _transitionCount = 0;
    _transitionDuration = 0;
    _propertyArray = nil;
    _oldFilterStyles = nil;
    _filterStyles= nil;
}

- (NSMutableDictionary *)_filterStyles
{
    return self.filterStyles;
}

- (NSMutableDictionary *)_oldFilterStyles
{
    return self.oldFilterStyles;
}

#pragma mark UnitBezierp
- (void)unitBezierp1x:(double)p1x p1y:(double)p1y p2x:(double)p2x p2y:(double)p2y
{
    cx = 3.0 * p1x;
    bx = 3.0 * (p2x - p1x) - cx;
    ax = 1.0 - cx -bx;
    
    cy = 3.0 * p1y;
    by = 3.0 * (p2y - p1y) - cy;
    ay = 1.0 - cy - by;
}

- (double)sampleCurveX:(double)t
{
    return ((ax * t + bx) * t + cx) * t;
}

- (double)sampleCurveY:(double)t
{
    return ((ay * t + by) * t + cy) * t;
}

- (double)sampleCurveDerivativeX:(double)t
{
    return (3.0 * ax * t + 2.0 * bx) * t + cx;
}

- (double)solveCurveX:(double)x epsilon:(double)epsilon
{
    double t0;
    double t1;
    double t2;
    double x2;
    double d2;
    int i;
    
    for (t2 = x, i = 0; i < 8; i++) {
        x2 = [self sampleCurveX:t2] - x;
        if (fabs (x2) < epsilon)
            return t2;
        d2 = [self sampleCurveDerivativeX:t2];
        if (fabs(d2) < 1e-6)
            break;
        t2 = t2 - x2 / d2;
    }
    t0 = 0.0;
    t1 = 1.0;
    t2 = x;
    
    if (t2 < t0)
        return t0;
    if (t2 > t1)
        return t1;
    
    while (t0 < t1) {
        x2 = [self sampleCurveX:t2];
        if (fabs(x2 - x) < epsilon)
            return t2;
        if (x > x2)
            t0 = t2;
        else
            t1 = t2;
        t2 = (t1 - t0) * .5 + t0;
    }
    return t2;
}

- (double)solveWithx:(double)x epsilon:(double)epsilon
{
    return [self sampleCurveY:([self solveCurveX:x epsilon:epsilon])];
}
@end
