/*
 * 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 "WXComponent+Layout.h"
#import "WXComponent_internal.h"
#import "WXTransform.h"
#import "WXAssert.h"
#import "WXSDKInstance_private.h"
#import "WXComponent+BoxShadow.h"
#import "WXLog.h"
#import "WXMonitor.h"
#import "WXSDKInstance_performance.h"
#import "WXCellComponent.h"
#import "WXCoreBridge.h"

bool flexIsUndefined(float value) {
    return isnan(value);
}

@implementation WXComponent (Layout)

#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"

#pragma mark Public

- (void)setNeedsLayout
{
    if (_flexCssNode != nullptr) {
        _flexCssNode->markDirty();
    }
}

- (BOOL)needsLayout
{
    if (_flexCssNode != nullptr) {
        return _flexCssNode->isDirty();
    }
    else {
        return false;
    }
}

- (CGSize (^)(CGSize))measureBlock
{
    return nil;
}

- (void)layoutDidFinish
{
    WXAssertMainThread();
}

- (void)updateLayoutStyles:(NSDictionary*)styles
{
    WXPerformBlockOnComponentThread(^{
        [WXCoreBridge callUpdateStyle:self.weexInstance.instanceId ref:self.ref data:styles];
    });
}

#pragma mark Private

- (void)_setRenderObject:(void *)object
{
    if (object) {
        _flexCssNode = static_cast<WeexCore::WXCoreLayoutNode*>(object);
        _flexCssNode->setContext((__bridge void *)self); // bind
        if ([self measureBlock]) {
            _flexCssNode->setMeasureFunc(flexCssNodeMeasure);
        }
    }
    else if (_flexCssNode) {
        _flexCssNode->setContext(nullptr);
        _flexCssNode = nullptr;
    }
}

- (void)_updateCSSNodeStyles:(NSDictionary *)styles
{
    [self _fillCSSNode:styles isUpdate:YES];
}

-(void)_resetCSSNodeStyles:(NSArray *)styles
{
    [self _resetCSSNode:styles];
}

- (void)_frameDidCalculated:(BOOL)isChanged
{
    WXAssertComponentThread();
    if (isChanged && [self isKindOfClass:[WXCellComponent class]]) {
        CGFloat mainScreenWidth = [[UIScreen mainScreen] bounds].size.width;
        CGFloat mainScreenHeight = [[UIScreen mainScreen] bounds].size.height;
        if (mainScreenHeight/2 < _calculatedFrame.size.height && mainScreenWidth/2 < _calculatedFrame.size.width) {
            [self weexInstance].performance.cellExceedNum++;
            [self.weexInstance.apmInstance updateFSDiffStats:KEY_PAGE_STATS_CELL_EXCEED_NUM withDiffValue:1];
        }
    }
    
    if ([self isViewLoaded] && isChanged && [self isViewFrameSyncWithCalculated]) {
        
        __weak typeof(self) weakSelf = self;
        [self.weexInstance.componentManager _addUITask:^{
            __strong typeof(weakSelf) strongSelf = weakSelf;
            
            if (strongSelf == nil) {
                return;
            }
            
            // Check again incase that this property is set to NO in another UI task.
            if (![strongSelf isViewFrameSyncWithCalculated]) {
                return;
            }
            
            if (strongSelf->_transform && !CATransform3DEqualToTransform(strongSelf.layer.transform, CATransform3DIdentity)) {
                // From the UIView's frame documentation:
                // https://developer.apple.com/reference/uikit/uiview#//apple_ref/occ/instp/UIView/frame
                // Warning : If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
                // So layer's transform must be reset to CATransform3DIdentity before setFrame, otherwise frame will be incorrect
                strongSelf.layer.transform = CATransform3DIdentity;
            }
            
            WXBoxShadow* usingBoxShadow = [strongSelf _chooseBoxShadow];            
            if (!CGRectEqualToRect(strongSelf.view.frame,strongSelf.calculatedFrame)) {
                strongSelf.view.frame = strongSelf.calculatedFrame;
                strongSelf->_absolutePosition = CGPointMake(NAN, NAN);
                [strongSelf configBoxShadow:usingBoxShadow];
            } else {
                if (![strongSelf equalBoxShadow:usingBoxShadow withBoxShadow:strongSelf->_lastBoxShadow]) {
                    [strongSelf configBoxShadow:usingBoxShadow];
                }
            }
            
            [strongSelf _resetNativeBorderRadius];
            
            if ([WXUtility enableRTLLayoutDirection]) {
                if ([strongSelf isDirectionRTL] != strongSelf -> _isLastLayoutDirectionRTL) {
                    strongSelf -> _isLastLayoutDirectionRTL = [strongSelf isDirectionRTL];
                    [strongSelf _layoutDirectionDidChanged:[strongSelf isDirectionRTL]];
                }
            }
            
            if (strongSelf->_transform) {
                [strongSelf->_transform applyTransformForView:strongSelf.view];
            }
            
            [strongSelf _adjustForRTL];
            
            if (strongSelf->_backgroundImage) {
                [strongSelf setGradientLayer];
            }
            
            [strongSelf setNeedsDisplay];
        }];
    } else if ([WXUtility enableRTLLayoutDirection]) {
        // if frame is not change, we still need check was layoutDirection changed
        if ([self isDirectionRTL] != _isLastLayoutDirectionRTL) {
            self -> _isLastLayoutDirectionRTL = [self isDirectionRTL];
            __weak typeof(self) weakSelf = self;
            [self.weexInstance.componentManager _addUITask:^{
                __strong typeof(weakSelf) strongSelf = weakSelf;
                [strongSelf _layoutDirectionDidChanged:[strongSelf isDirectionRTL]];
                if (strongSelf->_transform) {
                    [strongSelf->_transform applyTransformForView:strongSelf.view];
                }
                [strongSelf _adjustForRTL];
            }];
        }
    }
}

- (void)_layoutDirectionDidChanged:(BOOL)isRTL {
    WXAssertMainThread();
    [self layoutDirectionDidChanged:isRTL];
}

- (void)layoutDirectionDidChanged:(BOOL)isRTL {
    
}

- (void)_layoutDidFinish
{
    WXAssertMainThread();

    if (_positionType == WXPositionTypeSticky) {
        [self.ancestorScroller adjustSticky];
    }

    [self layoutDidFinish];
}

#define WX_STYLE_FLEX_NODE_JUDGE_LEGAL(key) styles[key]&&!isnan([WXConvert WXPixelType:styles[key] scaleFactor:self.weexInstance.pixelScaleFactor])

- (CGFloat)WXPixelType:(id)value
{
    return [WXConvert WXPixelType:value scaleFactor:self.weexInstance.pixelScaleFactor];
}

- (void)_fillCSSNode:(NSDictionary *)styles isUpdate:(BOOL)isUpdate
{
    if (_flexCssNode == nullptr) {
        return;
    }

    BOOL needLayout = NO;
    
    // CSS direction for RTL Layout
    if (styles[@"direction"]) {
        _flexCssNode->setDirection([self fxDirection:styles[@"direction"]], isUpdate);
        needLayout = YES;
    }
    
    // flex
    if (styles[@"flex"]) {
        _flexCssNode->set_flex([WXConvert CGFloat:styles[@"flex"]]);
        needLayout = YES;
    }
    if (isnan(_flexCssNode->getFlex())) {
        // to make the default flex value is zero, yoga is nan, maybe this can configured by yoga config
        _flexCssNode->set_flex(0);
        needLayout = YES;
    }
    
    if (styles[@"flexDirection"]) {
        _flexCssNode->setFlexDirection([self fxFlexDirection:styles[@"flexDirection"]], isUpdate);
        needLayout = YES;
    }
    if (styles[@"alignItems"]) {
        _flexCssNode->setAlignItems([self fxAlign:styles[@"alignItems"]]);
        needLayout = YES;
    }
    if (styles[@"alignSelf"]) {
        _flexCssNode->setAlignSelf([self fxAlignSelf:styles[@"alignSelf"]]);
        needLayout = YES;
    }
    if (styles[@"flexWrap"]) {
        _flexCssNode->setFlexWrap([self fxWrap:styles[@"flexWrap"]]);
        needLayout = YES;
    }
    if (styles[@"justifyContent"]) {
        _flexCssNode->setJustifyContent([self fxJustify:styles[@"justifyContent"]]);
        needLayout = YES;
    }
    
    // position
    if (styles[@"position"]) {
        _flexCssNode->setStylePositionType([self fxPositionType:styles[@"position"]]);
        needLayout = YES;
    }
    if (styles[@"top"]) {
        _flexCssNode->setStylePosition(WeexCore::kPositionEdgeTop,
                                       [self judgePropValuePropValue:styles[@"top"] defaultValue:NAN]);
        needLayout = YES;
    }
    if (styles[@"left"]) {
        _flexCssNode->setStylePosition(WeexCore::kPositionEdgeLeft,
                                       [self judgePropValuePropValue:styles[@"left"] defaultValue:NAN]);
        needLayout = YES;
    }
    if(styles[@"right"]) {
        _flexCssNode->setStylePosition(WeexCore::kPositionEdgeRight,
                                       [self judgePropValuePropValue:styles[@"right"] defaultValue:NAN]);
        needLayout = YES;
    }
    if (styles[@"bottom"]) {
        _flexCssNode->setStylePosition(WeexCore::kPositionEdgeBottom,
                                       [self judgePropValuePropValue:styles[@"bottom"] defaultValue:NAN]);
        needLayout = YES;
    }
    
    // dimension
    if (styles[@"width"]) {
        _flexCssNode->setStyleWidth([self judgePropValuePropValue:styles[@"width"] defaultValue:NAN], isUpdate);
        needLayout = YES;
    }
    if (styles[@"height"]) {
        _flexCssNode->setStyleHeight([self judgePropValuePropValue:styles[@"height"] defaultValue:NAN]);
        needLayout = YES;
    }
    if (styles[@"minWidth"]) {
        _flexCssNode->setMinWidth([self judgePropValuePropValue:styles[@"minWidth"] defaultValue:NAN], isUpdate);
        needLayout = YES;
    }
    if (styles[@"minHeight"]) {
        _flexCssNode->setMinHeight([self judgePropValuePropValue:styles[@"minHeight"] defaultValue:NAN]);
        needLayout = YES;
    }
    if (styles[@"maxWidth"]) {
        _flexCssNode->setMaxWidth([self judgePropValuePropValue:styles[@"maxWidth"] defaultValue:NAN], isUpdate);
        needLayout = YES;
    }
    if (styles[@"maxHeight"]) {
        _flexCssNode->setMaxHeight([self judgePropValuePropValue:styles[@"maxHeight"] defaultValue:NAN]);
        needLayout = YES;
    }
    
    // margin
    if (styles[@"margin"]) {
        _flexCssNode->setMargin(WeexCore::kMarginALL,
                                [self judgePropValuePropValue:styles[@"margin"] defaultValue:0]);
        needLayout = YES;
    }
    if (styles[@"marginTop"]) {
        _flexCssNode->setMargin(WeexCore::kMarginTop,
                                [self judgePropValuePropValue:styles[@"marginTop"] defaultValue:0]);
        needLayout = YES;
    }
    if (styles[@"marginBottom"]) {
        _flexCssNode->setMargin(WeexCore::kMarginBottom,
                                [self judgePropValuePropValue:styles[@"marginBottom"] defaultValue:0]);
        needLayout = YES;
    }
    if (styles[@"marginRight"]) {
        _flexCssNode->setMargin(WeexCore::kMarginRight,
                                [self judgePropValuePropValue:styles[@"marginRight"] defaultValue:0]);
    }
    if (styles[@"marginLeft"]) {
        _flexCssNode->setMargin(WeexCore::kMarginLeft,
                                [self judgePropValuePropValue:styles[@"marginLeft"] defaultValue:0]);
        needLayout = YES;
    }
    
    // border
    if (styles[@"borderWidth"]) {
        _flexCssNode->setBorderWidth(WeexCore::kBorderWidthALL,
                                     [self judgePropValuePropValue:styles[@"borderWidth"] defaultValue:0]);
        needLayout = YES;
    }
    if (styles[@"borderTopWidth"]) {
        _flexCssNode->setBorderWidth(WeexCore::kBorderWidthTop,
                                     [self judgePropValuePropValue:styles[@"borderTopWidth"] defaultValue:0]);
        needLayout = YES;
    }
    
    if (styles[@"borderLeftWidth"]) {
        _flexCssNode->setBorderWidth(WeexCore::kBorderWidthLeft,
                                     [self judgePropValuePropValue:styles[@"borderLeftWidth"] defaultValue:0]);
        needLayout = YES;
    }
    
    if (styles[@"borderBottomWidth"]) {
        _flexCssNode->setBorderWidth(WeexCore::kBorderWidthBottom,
                                     [self judgePropValuePropValue:styles[@"borderBottomWidth"] defaultValue:0]);
        needLayout = YES;
    }
    if (styles[@"borderRightWidth"]) {
        _flexCssNode->setBorderWidth(WeexCore::kBorderWidthRight,
                                     [self judgePropValuePropValue:styles[@"borderRightWidth"] defaultValue:0]);
        needLayout = YES;
    }
    
    // padding
    if (styles[@"padding"]) {
        _flexCssNode->setPadding(WeexCore::kPaddingALL,
                                 [self judgePropValuePropValue:styles[@"padding"] defaultValue:0]);
        needLayout = YES;
    }
    if (styles[@"paddingTop"]) {
        _flexCssNode->setPadding(WeexCore::kPaddingTop,
                                 [self judgePropValuePropValue:styles[@"paddingTop"] defaultValue:0]);
        needLayout = YES;
    }
    if (styles[@"paddingLeft"]) {
        _flexCssNode->setPadding(WeexCore::kPaddingLeft,
                                 [self judgePropValuePropValue:styles[@"paddingLeft"] defaultValue:0]);
        needLayout = YES;
    }
    if (styles[@"paddingBottom"]) {
        _flexCssNode->setPadding(WeexCore::kPaddingBottom,
                                 [self judgePropValuePropValue:styles[@"paddingBottom"] defaultValue:0]);
        needLayout = YES;
    }
    if (styles[@"paddingRight"]) {
        _flexCssNode->setPadding(WeexCore::kPaddingRight,
                                 [self judgePropValuePropValue:styles[@"paddingRight"] defaultValue:0]);
        needLayout = YES;
    }
    
    if (needLayout) {
        [self setNeedsLayout];
    }
}

- (CGFloat)judgePropValuePropValue:(id)propValue defaultValue:(CGFloat)defaultValue
{
    CGFloat convertValue = (CGFloat)[WXConvert WXFlexPixelType:propValue scaleFactor:self.weexInstance.pixelScaleFactor];
    if (!isnan(convertValue)) {
        return convertValue;
    }
    return defaultValue;
}

- (float)getCssStyleValueForKey:(NSString *)key
{
    /*
     *      width, height, min-width, min-height, max-width, max-height,
     *      margin-(left/right/top/bottom)
     *      padding-(left/right/top/bottom)
     *      border-(left/right/top/bottom)-width
     *      left, right, top, bottom
     *      flex-grow
     */
    WXAssert(_flexCssNode != nullptr, @"Css node is null.");
    if (_flexCssNode == nullptr) {
        return NAN;
    }
    
    std::string ckey = [key UTF8String];
    if (ckey == "width") return _flexCssNode->getStyleWidth();
    if (ckey == "height") return _flexCssNode->getStyleHeight();
    if (ckey == "min-width") return _flexCssNode->getMinWidth();
    if (ckey == "min-height") return _flexCssNode->getMinHeight();
    if (ckey == "max-width") return _flexCssNode->getMaxWidth();
    if (ckey == "max-height") return _flexCssNode->getMaxHeight();
    if (ckey == "margin-left") return _flexCssNode->getMarginLeft();
    if (ckey == "margin-right") return _flexCssNode->getMarginRight();
    if (ckey == "margin-top") return _flexCssNode->getMarginTop();
    if (ckey == "margin-bottom") return _flexCssNode->getMarginBottom();
    if (ckey == "padding-left") return _flexCssNode->getPaddingLeft();
    if (ckey == "padding-right") return _flexCssNode->getPaddingRight();
    if (ckey == "padding-top") return _flexCssNode->getPaddingTop();
    if (ckey == "padding-bottom") return _flexCssNode->getPaddingBottom();
    if (ckey == "border-left-width") return _flexCssNode->getBorderWidthLeft();
    if (ckey == "border-right-width") return _flexCssNode->getBorderWidthRight();
    if (ckey == "border-top-width") return _flexCssNode->getBorderWidthTop();
    if (ckey == "border-bottom-width") return _flexCssNode->getBorderWidthBottom();
    if (ckey == "left") return _flexCssNode->getStylePositionLeft();
    if (ckey == "right") return _flexCssNode->getStylePositionRight();
    if (ckey == "top") return _flexCssNode->getStylePositionTop();
    if (ckey == "bottom") return _flexCssNode->getStylePositionBottom();
    if (ckey == "flex-grow") return _flexCssNode->getFlex();
    
    WXAssert(NO, @"Invalid css style key %@", key);
    return NAN;
}

- (WXCoreFlexDirection)getCssStyleFlexDirection
{
    WXAssert(_flexCssNode != nullptr, @"Css node is null.");
    return _flexCssNode ? _flexCssNode->getFlexDirection() : kFlexDirectionColumn;
}

- (WXCoreFlexWrap)getCssStyleFlexWrap
{
    WXAssert(_flexCssNode != nullptr, @"Css node is null.");
    return _flexCssNode ? _flexCssNode->getFlexWrap() : kNoWrap;
}

- (WXCoreJustifyContent)getCssStyleJustifyContent
{
    WXAssert(_flexCssNode != nullptr, @"Css node is null.");
    return _flexCssNode ? _flexCssNode->getJustifyContent() : kJustifyFlexStart;
}

- (WXCoreAlignItems)getCssStyleAlignItems
{
    WXAssert(_flexCssNode != nullptr, @"Css node is null.");
    return _flexCssNode ? _flexCssNode->getAlignItems() : kAlignItemsStretch;
}

- (WXCoreAlignSelf)getCssStyleAlignSelf
{
    WXAssert(_flexCssNode != nullptr, @"Css node is null.");
    return _flexCssNode ? _flexCssNode->getAlignSelf() : kAlignSelfAuto;
}

- (WXCorePositionType)getCssStylePositionType
{
    WXAssert(_flexCssNode != nullptr, @"Css node is null.");
    return _flexCssNode ? _flexCssNode->getStylePositionType() : kRelative;
}

- (WXCoreDirection)getCssDirection
{
    WXAssert(_flexCssNode != nullptr, @"Css node is null.");
    return _flexCssNode ? _flexCssNode->getDirection() : WEEXCORE_CSS_DEFAULT_DIRECTION;
}

- (NSString*)convertLayoutValueToStyleValue:(NSString*)valueName
{
    if (_flexCssNode == nullptr) {
        return @"0";
    }
    
    float layoutValue = 0;
    if ([valueName isEqualToString:@"left"])
        layoutValue = _flexCssNode->getLayoutPositionLeft();
    else if ([valueName isEqualToString:@"right"])
        layoutValue = _flexCssNode->getLayoutPositionRight();
    else if ([valueName isEqualToString:@"top"])
        layoutValue = _flexCssNode->getLayoutPositionTop();
    else if ([valueName isEqualToString:@"bottom"])
        layoutValue = _flexCssNode->getLayoutPositionBottom();
    else if ([valueName isEqualToString:@"width"])
        layoutValue = _flexCssNode->getLayoutWidth();
    else if ([valueName isEqualToString:@"height"])
        layoutValue = _flexCssNode->getLayoutHeight();
    else
        return @"0";
    
    layoutValue /= self.weexInstance.pixelScaleFactor;
    return [NSString stringWithFormat:@"%f", layoutValue];
}

- (CGFloat)safeContainerStyleWidth
{
    if (_flexCssNode == nullptr) {
        return 0.0f;
    }
    
    CGFloat thisValue = _flexCssNode->getStyleWidth();
    if (isnan(thisValue)) {
        if (_flexCssNode->getParent()) {
            thisValue = _flexCssNode->getParent()->getLayoutWidth(); // parent may be layout done
            if (isnan(thisValue)) {
                thisValue = _flexCssNode->getParent()->getStyleWidth();
            }
        }
    }
    
    if (isnan(thisValue)) {
        thisValue = self.weexInstance.frame.size.width;
    }
    
    if (isnan(thisValue) || thisValue == 0.0f) {
        thisValue = [UIScreen mainScreen].bounds.size.width;
    }
    
    return thisValue;
}

#define WX_FLEX_STYLE_RESET_CSS_NODE(key, defaultValue)\
do {\
    WX_FLEX_STYLE_RESET_CSS_NODE_GIVEN_KEY(key,key,defaultValue)\
} while(0);

#define WX_FLEX_STYLE_RESET_CSS_NODE_GIVEN_KEY(judgeKey, propKey, defaultValue)\
do {\
    if (styles && [styles containsObject:@#judgeKey]) {\
        NSMutableDictionary *resetStyleDic = [[NSMutableDictionary alloc] init];\
        [resetStyleDic setValue:defaultValue forKey:@#propKey];\
        [self _updateCSSNodeStyles:resetStyleDic];\
        [self setNeedsLayout];\
    }\
} while(0);

#define WX_FLEX_STYLE_RESET_CSS_NODE_GIVEN_DIRECTION_KEY(judgeKey, propTopKey,propLeftKey,propRightKey,propBottomKey, defaultValue)\
do {\
    if (styles && [styles containsObject:@#judgeKey]) {\
        NSMutableDictionary *resetStyleDic = [[NSMutableDictionary alloc] init];\
        [resetStyleDic setValue:defaultValue forKey:@#propTopKey];\
        [resetStyleDic setValue:defaultValue forKey:@#propLeftKey];\
        [resetStyleDic setValue:defaultValue forKey:@#propRightKey];\
        [resetStyleDic setValue:defaultValue forKey:@#propBottomKey];\
        [self _updateCSSNodeStyles:resetStyleDic];\
        [self setNeedsLayout];\
    }\
} while(0);


- (void)_resetCSSNode:(NSArray *)styles
{
        if (styles.count<=0) {
            return;
        }
    
        WX_FLEX_STYLE_RESET_CSS_NODE(direction, @(WeexCore::kDirectionInherit))
    
        WX_FLEX_STYLE_RESET_CSS_NODE(flex, @0.0)
        WX_FLEX_STYLE_RESET_CSS_NODE(flexDirection, @(WeexCore::kFlexDirectionColumn))
        WX_FLEX_STYLE_RESET_CSS_NODE(alignItems, @(WeexCore::kAlignItemsStretch))
        WX_FLEX_STYLE_RESET_CSS_NODE(alignSelf, @(WeexCore::kAlignSelfAuto))
        WX_FLEX_STYLE_RESET_CSS_NODE(flexWrap, @(WeexCore::kNoWrap))
        WX_FLEX_STYLE_RESET_CSS_NODE(justifyContent, @(WeexCore::kJustifyFlexStart))
        
        // position
        WX_FLEX_STYLE_RESET_CSS_NODE(position, @(WeexCore::kRelative))
        WX_FLEX_STYLE_RESET_CSS_NODE(top, @(NAN))
        WX_FLEX_STYLE_RESET_CSS_NODE(left, @(NAN))
        WX_FLEX_STYLE_RESET_CSS_NODE(right, @(NAN))
        WX_FLEX_STYLE_RESET_CSS_NODE(bottom, @(NAN))
        
        // dimension
        WX_FLEX_STYLE_RESET_CSS_NODE(width, @(NAN))
        WX_FLEX_STYLE_RESET_CSS_NODE(height, @(NAN))
        WX_FLEX_STYLE_RESET_CSS_NODE(minWidth, @(NAN))
        WX_FLEX_STYLE_RESET_CSS_NODE(minHeight, @(NAN))
        WX_FLEX_STYLE_RESET_CSS_NODE(maxWidth, @(NAN))
        WX_FLEX_STYLE_RESET_CSS_NODE(maxHeight, @(NAN))
        
        // margin
        WX_FLEX_STYLE_RESET_CSS_NODE_GIVEN_DIRECTION_KEY(margin
                                                         ,marginTop
                                                         ,marginLeft
                                                         ,marginRight
                                                         ,marginBottom
                                                         , @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(marginTop, @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(marginLeft, @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(marginRight, @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(marginBottom, @(0.0))
        
        // border
        WX_FLEX_STYLE_RESET_CSS_NODE_GIVEN_DIRECTION_KEY(borderWidth
                                                         , borderTopWidth
                                                         , borderLeftWidth
                                                         , borderRightWidth
                                                         , borderBottomWidth
                                                         , @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(borderTopWidth, @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(borderLeftWidth, @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(borderRightWidth, @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(borderBottomWidth, @(0.0))
        
        // padding
        WX_FLEX_STYLE_RESET_CSS_NODE_GIVEN_DIRECTION_KEY(padding
                                                         , paddingTop
                                                         , paddingLeft
                                                         , paddingRight
                                                         , paddingBottom
                                                         , @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(paddingTop, @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(paddingLeft, @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(paddingRight, @(0.0))
        WX_FLEX_STYLE_RESET_CSS_NODE(paddingBottom, @(0.0))

}

#pragma mark CSS Node Override

static WeexCore::WXCoreSize flexCssNodeMeasure(WeexCore::WXCoreLayoutNode *node, float width, WeexCore::MeasureMode widthMeasureMode,float height, WeexCore::MeasureMode heightMeasureMode){
    
    if (node->getContext() == nullptr) { //为空
        return WeexCore::WXCoreSize();
    }
    WXComponent *component = (__bridge WXComponent *)(node->getContext());
    
    if (![component respondsToSelector:@selector(measureBlock)]) {
        return WeexCore::WXCoreSize();
    }
    
    CGSize (^measureBlock)(CGSize) = [component measureBlock];
    
    if (!measureBlock) {
        return WeexCore::WXCoreSize();
    }
    
    CGSize constrainedSize = CGSizeMake(width, height);
    CGSize resultSize = measureBlock(constrainedSize);
#ifdef DEBUG
    WXLogDebug(@"flexLayout -> measureblock %@, resultSize:%@",
          component.type,
          NSStringFromCGSize(resultSize)
          );
#endif
    WeexCore::WXCoreSize size;
    size.height=(float)resultSize.height;
    size.width=(float)resultSize.width;
    return size;
}

-(WeexCore::WXCorePositionType)fxPositionType:(id)value
{
    if([value isKindOfClass:[NSString class]]){
        if ([value isEqualToString:@"absolute"]) {
            return WeexCore::kAbsolute;
        } else if ([value isEqualToString:@"relative"]) {
            return WeexCore::kRelative;
        } else if ([value isEqualToString:@"fixed"]) {
            return WeexCore::kFixed;
        } else if ([value isEqualToString:@"sticky"]) {
            return WeexCore::kRelative;
        }
    }
    return WeexCore::kRelative;
}

- (WeexCore::WXCoreDirection)fxDirection:(id)value
{
    if([value isKindOfClass:[NSString class]]){
        if ([value isEqualToString:@"rtl"]) {
            return WeexCore::kDirectionRTL;
        } else if ([value isEqualToString:@"ltr"]) {
            return WeexCore::kDirectionLTR;
        }
    }
    return WeexCore::kDirectionInherit;
}

- (WeexCore::WXCoreFlexDirection)fxFlexDirection:(id)value
{
    if([value isKindOfClass:[NSString class]]){
        if ([value isEqualToString:@"column"]) {
            return WeexCore::kFlexDirectionColumn;
        } else if ([value isEqualToString:@"column-reverse"]) {
            return WeexCore::kFlexDirectionColumnReverse;
        } else if ([value isEqualToString:@"row"]) {
            return WeexCore::kFlexDirectionRow;
        } else if ([value isEqualToString:@"row-reverse"]) {
            return WeexCore::kFlexDirectionRowReverse;
        }
    }
    return WeexCore::kFlexDirectionColumn;
}

//TODO
- (WeexCore::WXCoreAlignItems)fxAlign:(id)value
{
    if([value isKindOfClass:[NSString class]]){
        if ([value isEqualToString:@"stretch"]) {
            return WeexCore::kAlignItemsStretch;
        } else if ([value isEqualToString:@"flex-start"]) {
            return WeexCore::kAlignItemsFlexStart;
        } else if ([value isEqualToString:@"flex-end"]) {
            return WeexCore::kAlignItemsFlexEnd;
        } else if ([value isEqualToString:@"center"]) {
            return WeexCore::kAlignItemsCenter;
            //return WXCoreFlexLayout::WXCore_AlignItems_Center;
        } else if ([value isEqualToString:@"auto"]) {//!OCLint
//            return YGAlignAuto;
        } else if ([value isEqualToString:@"baseline"]) {//!OCLint
//            return YGAlignBaseline;
        }
    }
    
    return WeexCore::kAlignItemsStretch;
}

- (WeexCore::WXCoreAlignSelf)fxAlignSelf:(id)value
{
    if([value isKindOfClass:[NSString class]]){
        if ([value isEqualToString:@"stretch"]) {
            return WeexCore::kAlignSelfStretch;
        } else if ([value isEqualToString:@"flex-start"]) {
            return WeexCore::kAlignSelfFlexStart;
        } else if ([value isEqualToString:@"flex-end"]) {
            return WeexCore::kAlignSelfFlexEnd;
        } else if ([value isEqualToString:@"center"]) {
            return WeexCore::kAlignSelfCenter;
        } else if ([value isEqualToString:@"auto"]) {
            return WeexCore::kAlignSelfAuto;
        } else if ([value isEqualToString:@"baseline"]) {//!OCLint
            //            return YGAlignBaseline;
        }
    }
    
    return WeexCore::kAlignSelfStretch;
}

- (WeexCore::WXCoreFlexWrap)fxWrap:(id)value
{
    if([value isKindOfClass:[NSString class]]) {
        if ([value isEqualToString:@"nowrap"]) {
            return WeexCore::kNoWrap;
        } else if ([value isEqualToString:@"wrap"]) {
            return WeexCore::kWrap;
        } else if ([value isEqualToString:@"wrap-reverse"]) {
            return WeexCore::kWrapReverse;
        }
    }
    return WeexCore::kNoWrap;
}

- (WeexCore::WXCoreJustifyContent)fxJustify:(id)value
{
    if([value isKindOfClass:[NSString class]]){
        if ([value isEqualToString:@"flex-start"]) {
            return WeexCore::kJustifyFlexStart;
        } else if ([value isEqualToString:@"center"]) {
            return WeexCore::kJustifyCenter;
        } else if ([value isEqualToString:@"flex-end"]) {
            return WeexCore::kJustifyFlexEnd;
        } else if ([value isEqualToString:@"space-between"]) {
            return WeexCore::kJustifySpaceBetween;
        } else if ([value isEqualToString:@"space-around"]) {
            return WeexCore::kJustifySpaceAround;
        }
    }
    return WeexCore::kJustifyFlexStart;
}

- (void)removeSubcomponentCssNode:(WXComponent *)subcomponent
{
    auto node = subcomponent->_flexCssNode;
    if (node) {
        if (_flexCssNode) {
            _flexCssNode->removeChild(node);
        }
        
        [subcomponent _setRenderObject:nullptr];
        
        // unbind subcomponents of subcomponent
        NSMutableArray* sub_subcomponents = [[NSMutableArray alloc] init];
        [subcomponent _collectSubcomponents:sub_subcomponents];
        for (WXComponent* c in sub_subcomponents) {
            [c _setRenderObject:nullptr];
        }
        
        [WXCoreBridge removeRenderObjectFromMap:subcomponent.weexInstance.instanceId object:node];
        delete node; // also will delete all children recursively
    }
}

#pragma mark - RTL

- (BOOL)isDirectionRTL {
    if (![WXUtility enableRTLLayoutDirection]) return NO;

    return _isLayoutDirectionRTL;
}

- (void)_adjustForRTL {
    if (![WXUtility enableRTLLayoutDirection]) return;
    
    if (self->_positionType == WXPositionTypeFixed) return;
    
    if (self.supercomponent && self.supercomponent.isDirectionRTL && [self.supercomponent shouldTransformSubviewsWhenRTL]) {
        if (_transform) {
            self.view.layer.transform = CATransform3DConcat(self.view.layer.transform, CATransform3DScale(CATransform3DIdentity, -1, 1, 1));
        } else {
            self.view.layer.transform = CATransform3DScale(CATransform3DIdentity, -1, 1, 1);
        }
    } else {
        if (!_transform) {
            self.view.layer.transform = CATransform3DIdentity;
        }
    }
}

// Now we scrollView RTL solution is tranform
// so scrollView need tranform subviews when RTL by default
// if your component view is not scrollView but also implement RTL layout by tranform，you need return YES
- (BOOL)shouldTransformSubviewsWhenRTL {
    return [self.view isKindOfClass:[UIScrollView class]];
}

- (void)_setIsLayoutRTL:(BOOL)isRTL {
    _isLayoutDirectionRTL = isRTL;
}

@end
