/**
 * 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.
 */
#ifdef __cplusplus

#ifndef WEEXCORE_FLEXLAYOUT_WXCORELAYOUTNODE_H
#define WEEXCORE_FLEXLAYOUT_WXCORELAYOUTNODE_H

#include "style.h"
#include "flex_enum.h"
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>

namespace WeexCore {

  class WXCoreLayoutNode;

  class WXCoreFlexLine;

  enum FormattingContext {
    kBFC,
    kNonBFC,
  } ;

  enum MeasureMode {
    kUnspecified = 0,
    kExactly,
  } ;

  struct WXCoreSize {
   private:
    float hypotheticalWidth;
    float hypotheticalHeight;
   public:
    friend class WXCoreLayoutNode;
    float width;
    float height;

    WXCoreSize() : hypotheticalWidth(NAN),
                   hypotheticalHeight(NAN),
                   width(0), height(0) {}

    inline void reset() {
      hypotheticalWidth = NAN ;
      hypotheticalHeight = NAN;
      width = 0;
      height = 0;
    }

    inline bool isNAN() {
      return isnan(width) || isnan(height);
    }
  };

  /**
   * layout-result：layout-height、layout-width、position（left、right、top、bottom）
   */
  struct WXCorelayoutResult {
    WXCoreSize mLayoutSize;
    WXCorePosition mLayoutPosition;

    inline bool isNAN() {
      return mLayoutSize.isNAN() || mLayoutPosition.isNAN();
    }

    inline void reset() {
      mLayoutSize.reset();
      mLayoutPosition.reset();
    }
  };

  typedef WXCoreSize(*WXCoreMeasureFunc)(WXCoreLayoutNode *node, float width,
                                         MeasureMode widthMeasureMode,
                                         float height, MeasureMode heightMeasureMode);

  using Index = std::vector<WXCoreLayoutNode *>::size_type;

  /**
   * flie line
   */
  class WXCoreFlexLine {
  public:
    float mMainSize;

    float mCrossSize;

    Index mItemCount;

    float mTotalFlexGrow;

    float mTotalFlexibleSize;

    /**
     * Store the indices of the children views whose mAlignSelf property is stretch.
     * The stored indices are the absolute indices including all children in the Flexbox,
     * not the relative indices in this flex line.
     */
    std::vector<Index> mIndicesAlignSelfStretch;

    WXCoreFlexLine() : mMainSize(0),
                       mCrossSize(0),
                       mItemCount(0),
                       mTotalFlexGrow(0),
                       mTotalFlexibleSize(0) {
    }

    ~WXCoreFlexLine() {
      mMainSize = 0;
      mCrossSize = 0;
      mItemCount = 0;
      mTotalFlexGrow = 0;
      mTotalFlexibleSize = 0;
      mIndicesAlignSelfStretch.clear();
    }
  };

  /**
   * Layout node
   */
  class WXCoreLayoutNode {

  public:
      WXCoreLayoutNode() :
              mParent(nullptr),
              dirty(true),
              widthDirty{false},
              heightDirty{false},
              mHasNewLayout(true),
              mIsDestroy(false),
              measureFunc(nullptr) {
        mCssStyle = new WXCoreCSSStyle();
        mLayoutResult = new WXCorelayoutResult();
      }


      virtual ~WXCoreLayoutNode() {
        mIsDestroy = true;
        mHasNewLayout = true;
        dirty = true;
        measureFunc = nullptr;
        mParent = nullptr;
        mChildList.clear();
        BFCs.clear();
        NonBFCs.clear();
        mChildrenFrozen.clear();

        for (WXCoreFlexLine *flexLine : mFlexLines) {
          if (flexLine != nullptr) {
            delete flexLine;
            flexLine = nullptr;
          }
        }
        mFlexLines.clear();

        if (mCssStyle != nullptr) {
          delete mCssStyle;
          mCssStyle = nullptr;
        }

        if (mLayoutResult != nullptr) {
          delete mLayoutResult;
          mLayoutResult = nullptr;
        }
      }

  private:

    /**
     * Holds the 'frozen' state of children during measure. If a view is frozen it will no longer
     * expand regardless of mFlexGrow. Items are indexed by the child's
     * reordered index.
     */
    std::vector<bool> mChildrenFrozen;

    std::vector<WXCoreFlexLine *> mFlexLines;

    std::vector<WXCoreLayoutNode *> mChildList;

    std::vector<WXCoreLayoutNode *> BFCs;

    std::vector<WXCoreLayoutNode *> NonBFCs;

    WXCoreLayoutNode *mParent = nullptr;

    WXCoreCSSStyle *mCssStyle = nullptr;

    MeasureMode widthMeasureMode = kUnspecified;

    MeasureMode heightMeasureMode = kUnspecified;

    WXCorelayoutResult *mLayoutResult = nullptr;

    WXCorePosition *absoultePositon = nullptr;

    bool mHasNewLayout;

    bool dirty, widthDirty, heightDirty;

    bool mIsDestroy = true;
      
    bool mNeedsPlatformDependentLayout = false;

    WXCoreMeasureFunc measureFunc = nullptr;

    void *context = nullptr;

    /** ================================ Cache：Last calculate result =================================== **/

  public:


    /** ================================ Engine Entry Function =================================== **/

    void calculateLayout(const std::pair<float,float>&);

    /** ================================ measureFunc =================================== **/

    inline void setMeasureFunc(WXCoreMeasureFunc measure) {
      measureFunc = measure;
      markDirty();
    }

    inline bool haveMeasureFunc() const {
      return nullptr != measureFunc;
    }

    inline WXCoreMeasureFunc getMeasureFunc() const {
      return measureFunc;
    }

      /** ================================ context =================================== **/


    inline void *getContext() const {
      return context;
    }

    inline void setContext(void * const context) {
      this->context = context;
    }

    inline void copyStyle(WXCoreLayoutNode *srcNode) {
      if (memcmp(mCssStyle, srcNode->mCssStyle, sizeof(WXCoreCSSStyle)) != 0) {
        memcpy(mCssStyle, srcNode->mCssStyle, sizeof(WXCoreCSSStyle));
        markDirty();
      }
    }

    void copyFrom(WXCoreLayoutNode* srcNode){
      memcpy(mCssStyle, srcNode->mCssStyle, sizeof(WXCoreCSSStyle));
    }

    inline void copyMeasureFunc(WXCoreLayoutNode *srcNode) {
      if (memcmp(&measureFunc, &srcNode->measureFunc, sizeof(WXCoreMeasureFunc)) != 0) {
        memcpy(&measureFunc, &srcNode->measureFunc, sizeof(WXCoreMeasureFunc));
        markDirty();
      }
    }
      
      /** ================================ custom =================================== **/
    inline bool getNeedsPlatformDependentLayout() const {
      return mNeedsPlatformDependentLayout;
    }
      
    inline void setNeedsPlatformDependentLayout(bool v) {
      this->mNeedsPlatformDependentLayout = v;
    }
      
  private:

    /** ================================ measure =================================== **/

    inline void reset() {
      if (isDirty()) {
        mLayoutResult->reset();
        for (WXCoreFlexLine *flexLine : mFlexLines) {
          if (flexLine != nullptr) {
            delete flexLine;
            flexLine = nullptr;
          }
        }
        mFlexLines.clear();

        mChildrenFrozen.assign(getChildCount(kNonBFC), false);
      }
      widthMeasureMode = isnan(mCssStyle->mStyleWidth) ? kUnspecified : kExactly;
      heightMeasureMode = isnan(mCssStyle->mStyleHeight) ? kUnspecified : kExactly;
    }

    inline void setLayoutWidth(const float width) {
      if (mLayoutResult->mLayoutSize.width != width &&
          (!isnan(width) || !isnan(mLayoutResult->mLayoutSize.width))) {
        mLayoutResult->mLayoutSize.width = width;
        widthDirty = true;
        markDirty(false);
      }
    }

    inline void setLayoutHeight(const float height) {
      if (mLayoutResult->mLayoutSize.height != height &&
          (!isnan(height) || !isnan(mLayoutResult->mLayoutSize.height))) {
        mLayoutResult->mLayoutSize.height = height;
        heightDirty = true;
        markDirty(false);
      }
    }

    inline void setWidthMeasureMode(const MeasureMode measureMode) {
      if (widthMeasureMode != measureMode) {
        widthMeasureMode = measureMode;
        if (getChildCount(kNonBFC) > 0) {
          widthDirty = true;
        }
      }
    }

    inline void setHeightMeasureMode(const MeasureMode measureMode) {
      if (heightMeasureMode != measureMode) {
        heightMeasureMode = measureMode;
        if (getChildCount(kNonBFC) > 0) {
          heightDirty = true;
        }
      }
    }

    inline float firstLineCrossSize() const {
      float sum = sumPaddingBorderAlongAxis(this, !isMainAxisHorizontal(this));
      if (!mFlexLines.empty()) {
        sum += mFlexLines[0]->mCrossSize;
      }
      return sum;
    }

    inline float getSumOfCrossSize() const {
      float sum = sumPaddingBorderAlongAxis(this, !isMainAxisHorizontal(this));
      for (WXCoreFlexLine *flexLine: mFlexLines) {
        sum += flexLine->mCrossSize;
      }
      return sum;
    }

    inline bool isMainAxisHorizontal(const WXCoreLayoutNode* const node) const {
      return node->mCssStyle->mFlexDirection == kFlexDirectionRow ||
             node->mCssStyle->mFlexDirection == kFlexDirectionRowReverse;
    }

    inline bool isCrossExactly() const {
      return isMainAxisHorizontal(this) ? heightMeasureMode == kExactly
                                        : widthMeasureMode == kExactly;
    }

    inline float sumPaddingBorderAlongAxis(const WXCoreLayoutNode* const node, bool horizontal) const {
      float paddingBorderAlongAxis;
      if (horizontal) {
        paddingBorderAlongAxis =
            node->mCssStyle->mPadding.getPadding(kPaddingLeft) +
            node->mCssStyle->mPadding.getPadding(kPaddingRight) +
            node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthLeft) +
            node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthRight);
      } else {
        paddingBorderAlongAxis =
            node->mCssStyle->mPadding.getPadding(kPaddingTop) +
            node->mCssStyle->mPadding.getPadding(kPaddingBottom) +
            node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthTop) +
            node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthBottom);
      }
      return paddingBorderAlongAxis;
    }

    inline bool isWrapRequired(const float &width, const float &height,
                               const float &currentLength, const float &childLength) const {
      float freeMainSize = CalculateFreeSpaceAlongMainAxis(width, height, currentLength);
      return !isSingleFlexLine(freeMainSize) && freeMainSize < childLength;
    }

    //If width/height is NAN, ret is NAN, which property we use on purpose.
    virtual float CalculateFreeSpaceAlongMainAxis(const float &width, const float &height,
                                                  const float &currentLength) const{
      float ret;
      if(isMainAxisHorizontal(this)){
        ret = width - sumPaddingBorderAlongAxis(this, true) - currentLength;
      }
      else{
        ret = height - sumPaddingBorderAlongAxis(this, false) - currentLength;
      }
      return ret;
    }

    inline bool isSingleFlexLine(const float &mainSize) const {
      return mCssStyle->mFlexWrap == kNoWrap || isnan(mainSize);
    }

    inline void sumFlexGrow(const WXCoreLayoutNode* const child, WXCoreFlexLine* const flexLine, Index i){
      if (child->mCssStyle->mFlexGrow > 0) {
        flexLine->mTotalFlexGrow += child->mCssStyle->mFlexGrow;
        mChildrenFrozen[i] = false;
        if (isMainAxisHorizontal(this)) {
          if (!isnan(child->mLayoutResult->mLayoutSize.hypotheticalWidth)) {
            flexLine->mTotalFlexibleSize += child->mLayoutResult->mLayoutSize.hypotheticalWidth;
          }
        } else {
          if (!isnan(child->mLayoutResult->mLayoutSize.hypotheticalHeight)) {
            flexLine->mTotalFlexibleSize += child->mLayoutResult->mLayoutSize.hypotheticalHeight;
          }
        }
      } else {
        mChildrenFrozen[i] = true;
      }
    }

    inline void setMeasuredDimensionForFlex(
        const float width, const MeasureMode widthMeasureMode,
        const float height, const MeasureMode heightMeasureMode){
      float actualWidth, actualHeight;
      if (isMainAxisHorizontal(this)) {
        actualWidth = widthMeasureMode == kExactly ? width : getLargestMainSize();
        actualHeight = heightMeasureMode == kExactly ? height : getSumOfCrossSize();
      } else {
        actualHeight = heightMeasureMode == kExactly ? height : getLargestMainSize();
        actualWidth = widthMeasureMode == kExactly ? width : firstLineCrossSize();
      }
      setMeasuredDimension(actualWidth, actualHeight);
    }

    inline float calcItemSizeAlongAxis(const WXCoreLayoutNode* const node, const bool horizontal, const bool useHypotheticalSize = false) const {
      float ret;
      if (horizontal) {
        ret = node->mCssStyle->mMargin.getMargin(kMarginLeft) +
            node->mCssStyle->mMargin.getMargin(kMarginRight);
        ret += useHypotheticalSize ? node->mLayoutResult->mLayoutSize.hypotheticalWidth
                                   : node->mLayoutResult->mLayoutSize.width;
      } else {
        ret = node->mCssStyle->mMargin.getMargin(kMarginTop) +
            node->mCssStyle->mMargin.getMargin(kMarginBottom);
        ret += useHypotheticalSize ? node->mLayoutResult->mLayoutSize.hypotheticalHeight
                                   : node->mLayoutResult->mLayoutSize.height;
      }
      return ret;
    }

    inline void limitMainSizeForFlexGrow(WXCoreFlexLine* const flexLine, const Index childIndex,
                                  const float flexGrow) {
      mChildrenFrozen[childIndex] = true;
      flexLine->mTotalFlexGrow -= flexGrow;
    }

    inline void setMeasuredDimension(const float width, const float height) {
      mLayoutResult->mLayoutSize.width = width;
      mLayoutResult->mLayoutSize.height = height;
    }

    inline std::pair<bool, float> limitChildMainSize(WXCoreFlexLine* const flexLine, const WXCoreLayoutNode* const child,
                                                                       float childSizeAlongMainAxis, const Index childIndex){
      bool needsReexpand = false;
      if (isMainAxisHorizontal(this)) {
        if (!isnan(child->mCssStyle->mMaxWidth) &&
            childSizeAlongMainAxis > child->mCssStyle->mMaxWidth) {
          needsReexpand = true;
          childSizeAlongMainAxis = child->mCssStyle->mMaxWidth;
        } else if (!isnan(child->mCssStyle->mMinWidth) &&
            childSizeAlongMainAxis < child->mCssStyle->mMinWidth) {
          needsReexpand = true;
          childSizeAlongMainAxis = child->mCssStyle->mMinWidth;
        }
      } else {
        if (!isnan(child->mCssStyle->mMaxHeight) &&
            childSizeAlongMainAxis > child->mCssStyle->mMaxHeight) {
          needsReexpand = true;
          childSizeAlongMainAxis = child->mCssStyle->mMaxHeight;
        } else if (!isnan(child->mCssStyle->mMinHeight) &&
            childSizeAlongMainAxis < child->mCssStyle->mMinHeight) {
          needsReexpand = true;
          childSizeAlongMainAxis = child->mCssStyle->mMinHeight;
        }
      }
      limitMainSizeForFlexGrow(flexLine, childIndex, child->mCssStyle->mFlexGrow);
      return std::make_pair(needsReexpand, childSizeAlongMainAxis);
    }

    void updateLeftRightForAbsolute(float &left, float &right,
                                    const WXCorePadding &parentPadding,
                                    const WXCoreBorderWidth &parentBorder,
                                    const WXCoreSize &parentSize) const {
      if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft))) {
        if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeRight))) {
          ;
        } else {
          right += parentSize.width -
              (parentBorder.getBorderWidth(kBorderWidthRight) +
                  mCssStyle->mStylePosition.getPosition(kPositionEdgeRight)
                  + mLayoutResult->mLayoutSize.width);
          left += parentSize.width -
              (parentBorder.getBorderWidth(kBorderWidthRight) +
                  mCssStyle->mStylePosition.getPosition(kPositionEdgeRight)
                  + mLayoutResult->mLayoutSize.width);
        }
      } else {
        left += parentBorder.getBorderWidth(kBorderWidthLeft) +
            mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft);
        right += parentBorder.getBorderWidth(kBorderWidthLeft) +
            mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft);
      }
    }

    void updateTopBottomForAbsolute(float &top, float &bottom,
                                    const WXCorePadding &parentPadding,
                                    const WXCoreBorderWidth &parentBorder,
                                    const WXCoreSize &parentSize) const {
      if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeTop))) {
        if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom))) {
          ;
        } else {
          top += parentSize.height -
              (parentBorder.getBorderWidth(kBorderWidthBottom) +
                  mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom)
                  + mLayoutResult->mLayoutSize.height);
          bottom += parentSize.height -
              (parentBorder.getBorderWidth(kBorderWidthBottom) +
                  mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom)
                  + mLayoutResult->mLayoutSize.height);
        }
      } else {
        top += parentBorder.getBorderWidth(kBorderWidthTop) +
            mCssStyle->mStylePosition.getPosition(kPositionEdgeTop);
        bottom += parentBorder.getBorderWidth(kBorderWidthTop) +
            mCssStyle->mStylePosition.getPosition(kPositionEdgeTop);
      }
    }

    /** ================================ other =================================== **/

    inline void clearDirty() {
      dirty = false;
      widthDirty = false;
      heightDirty = false;
    }

    void
    measure(float, float, bool);

    void hypotheticalMeasure(float, float, bool = false);

    void measureLeafNode(float, float, bool, bool);

    void measureInternalNode(float, float, bool, bool);

    void updateCurrentFlexline(Index, WXCoreFlexLine *, Index, const WXCoreLayoutNode *, bool);

    void measureChild(WXCoreLayoutNode* , float, float, float, bool, bool);

    void adjustChildSize(WXCoreLayoutNode *, float);

    void adjustChildSize(const WXCoreLayoutNode *child,
                         const float currentMainSize,
                         const float parentWidth,
                         const float parentHeight,
                         float &childWidth,
                         float &childHeight) const;

    void stretchViewCrossSize();

    void stretchViewCrossSize(WXCoreLayoutNode *, float);

    Index expandItemsInFlexLine(WXCoreFlexLine *, float, Index);

    void checkSizeConstraints(WXCoreLayoutNode *, bool);

    void
    determineMainSize(float width, float height);

    void
    determineCrossSize(float, float, bool);

    void
    determineCrossSize(float, float, WXCoreFlexLine *);

    void setFrame(float, float, float, float);

    void setFrame(WXCorePosition*,float, float, float, float);

    /** ================================ layout =================================== **/

    void layout(float left, float top, float right, float bottom, bool, const std::pair<float,float>* = nullptr);

    void calcRelativeOffset(float &left, float &top, float &right, float &bottom) const ;

    void calcAbsoluteOffset(float &left, float &top, float &right, float &bottom, const std::pair<float,float>* = nullptr);

    void positionAbsoluteFlexItem(float &left, float &top, float &right, float &bottom);

    void onLayout(float left, float top, float right, float bottom, WXCoreLayoutNode* = nullptr, WXCoreFlexLine *const flexLine = nullptr);

    void layoutHorizontal(bool isRtl, float left, float top, float right, float bottom,
                          WXCoreLayoutNode*, WXCoreFlexLine *const flexLine);

    void layoutFlexlineHorizontal(const float width,
                                         const WXCoreFlexLine *const flexLine,
                                         float &childLeft,
                                         float &childRight,
                                         float &spaceBetweenItem) const;

    void layoutSingleChildHorizontal(WXCoreLayoutNode *node, WXCoreFlexLine *flexLine,
                                     WXCoreFlexWrap flexWrap, WXCoreAlignItems alignItems,
                                     float, float, float, float, bool);

    void layoutSingleChildHorizontal(const bool isRtl,
                                    const bool,
                                    float childBottom, float childTop,
                                    WXCoreFlexLine *const flexLine,
                                    WXCoreLayoutNode *const child,
                                    float&, float&);

    void layoutVertical(bool isRtl, bool fromBottomToTop, float left, float top, float right, float bottom,
                        WXCoreLayoutNode*, WXCoreFlexLine *const flexLine);

    void layoutFlexlineVertical(const float height,
                                const WXCoreFlexLine *const flexLine,
                                float &childTop,
                                float &childBottom,
                                float &spaceBetweenItem) const;
    void layoutSingleChildVertical(WXCoreLayoutNode *node, WXCoreFlexLine *flexLine,
                                   bool isRtl, WXCoreAlignItems alignItems,
                                   float, float, float, float, bool);

    void layoutSingleChildVertical(const bool isRtl, const bool fromBottomToTop,
                                   const bool absoluteFlexItem,
                                   const float childLeft, const float childRight,
                                   WXCoreFlexLine *const flexLine,
                                   WXCoreLayoutNode *const child,
                                   float& ,float&);

    void updateFlexLineForAbsoluteItem(WXCoreLayoutNode *const absoluteFlexItem, WXCoreFlexLine *const flexLine);

    void initFormatingContext(std::vector<WXCoreLayoutNode *> &BFCs);

    std::pair<bool,float> calculateBFCWidth(float, float);

    std::pair<bool,float> calculateBFCHeight(float, float);

    std::tuple<bool, float, float> calculateBFCDimension(const std::pair<float,float>&);

    virtual void OnLayoutBefore() {

    }

    virtual void OnLayoutAfter(float width, float height) {

    }


  public:

    /** ================================ tree =================================== **/

    inline Index getChildCount(FormattingContext formattingContext) const {
      switch (formattingContext) {
        case kNonBFC:
          return NonBFCs.size();
        case kBFC:
          return BFCs.size();
        default:
          return mChildList.size();
      }
    }

    inline Index getChildCount() const {
      return mChildList.size();
    }

    inline std::vector<WXCoreLayoutNode *>::const_iterator ChildListIterBegin() {
      return mChildList.cbegin();
    }

    inline std::vector<WXCoreLayoutNode *>::const_iterator ChildListIterEnd() {
      return mChildList.cend();
    }

    inline bool hasChild(const WXCoreLayoutNode* const child){
       if(std::find(mChildList.begin(), mChildList.end(), child) != mChildList.end()){
         return true;
       }else{
         return false;
       }
    }

    inline void removeChild(const WXCoreLayoutNode* const child) {
      for (int index = 0; index < mChildList.size(); index++) {
        if (child == mChildList[index]) {
          mChildList.erase(mChildList.begin() + index);
          break;
        }
      }
      markDirty();
    }

    inline void addChildAt(WXCoreLayoutNode* const child, Index index) {
      mChildList.insert(mChildList.begin() + index, child);
      child->mParent = this;
      markDirty();
    }

    inline WXCoreLayoutNode *getChildAt(const FormattingContext formattingContext, const Index index) const {
      switch (formattingContext) {
        case kNonBFC:
          return NonBFCs[index];
        case kBFC:
          return BFCs[index];
        default:
          return mChildList[index];
      }
    }

    inline WXCoreLayoutNode *getChildAt(const Index index) const {
      return mChildList[index];
    }

    inline WXCoreLayoutNode *getParent() const {
      return mParent;
    }

    inline void setParent(WXCoreLayoutNode * const parent, WXCoreLayoutNode * const child) const {
       child->mParent = parent;
    }

    inline bool isBFC(WXCoreLayoutNode* const node) const {
      return node->mCssStyle->mPositionType == kAbsolute || node->mCssStyle->mPositionType == kFixed;
    }

    /** ================================ margin =================================== **/

    inline float getMarginTop() const {
      return mCssStyle->mMargin.getMargin(kMarginTop);
    }

    inline float getMarginBottom() const {
      return mCssStyle->mMargin.getMargin(kMarginBottom);
    }

    inline float getMarginLeft() const  {
      return mCssStyle->mMargin.getMargin(kMarginLeft);
    }

    inline float getMarginRight() const {
      return mCssStyle->mMargin.getMargin(kMarginRight);
    }

    inline void setMargin(const WXCoreMarginEdge &edge, const float margin) {
      if (mCssStyle->mMargin.setMargin(edge, margin)) {
        markDirty();
      }
    }

    inline const WXCoreMargin &GetMargins() const {
      return mCssStyle->mMargin;
    }

    /** ================================ padding =================================== **/

    inline float getPaddingLeft() const {
      return mCssStyle->mPadding.getPadding(kPaddingLeft);
    }

    inline float getPaddingRight() const {
      return mCssStyle->mPadding.getPadding(kPaddingRight);
    }

    inline float getPaddingTop() const {
      return mCssStyle->mPadding.getPadding(kPaddingTop);
    }

    inline float getPaddingBottom() const {
      return mCssStyle->mPadding.getPadding(kPaddingBottom);
    }

    inline void setPadding(const WXCorePaddingEdge edge, const float padding) {
      if (mCssStyle->mPadding.setPadding(edge, padding)) {
        markDirty();
      }
    }

    inline const WXCorePadding &GetPaddings() const {
      return mCssStyle->mPadding;
    }

    /** ================================ border-width =================================== **/

    inline float getBorderWidthLeft() const {
      return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthLeft);
    }

    inline float getBorderWidthRight() const {
      return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthRight);
    }

    inline float getBorderWidthTop() const {
      return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthTop);
    }

    inline float getBorderWidthBottom() const {
      return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthBottom);
    }

    inline void setBorderWidth(const WXCoreBorderWidthEdge edge, const float borderWidth) {
      if (mCssStyle->mBorderWidth.setBorderWidth(edge, borderWidth)) {
        markDirty();
      }
    }

    inline const WXCoreBorderWidth &GetBorders() const {
      return mCssStyle->mBorderWidth;
    }

    /** ================================ position-type =================================== **/

    inline void setStylePositionType(const WXCorePositionType positionType) {
      if (mCssStyle->mPositionType != positionType) {
        mCssStyle->mPositionType = positionType;
        markDirty();
      }
    }

    inline WXCorePositionType getStylePositionType() const {
      return mCssStyle->mPositionType;
    }


    /** ================================ position =================================== **/

    inline float getStylePositionTop() const {
      return mCssStyle->mStylePosition.getPosition(kPositionEdgeTop);
    }

    inline float getStylePositionBottom() const {
      return mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom);
    }

    inline float getStylePositionLeft() const {
      return mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft);
    }

    inline float getStylePositionRight() const {
      return mCssStyle->mStylePosition.getPosition(kPositionEdgeRight);
    }

    inline void setStylePosition(const WXCorePositionEdge edge, const float positionRight) {
      if (mCssStyle->mStylePosition.setPosition(edge, positionRight))
        markDirty();
    }


    /** ================================ dimension =================================== **/

    inline void setStyleWidthLevel(const DimensionLevel level) const {
      if (mCssStyle->mStyleWidthLevel != level) {
        mCssStyle->mStyleWidthLevel = level;
      }
    }

    inline void setStyleHeightLevel(const DimensionLevel level) const {
      if (mCssStyle->mStyleHeightLevel != level) {
        mCssStyle->mStyleHeightLevel = level;
      }
    }

    inline DimensionLevel getStyleHeightLevel() const {
      return mCssStyle->mStyleHeightLevel;
    }

    inline DimensionLevel getStyleWidthLevel() const {
      return mCssStyle->mStyleWidthLevel;
    }

    inline void setStyleWidth(const float width, const bool updating) {
      if (mCssStyle->mStyleWidth != width) {
        mCssStyle->mStyleWidth = width;
        markDirty();
        if(updating) {
          markChildrenDirty(true);
        }
      }
    }

    inline void setStyleWidthToNAN() {
      if (!isnan(mCssStyle->mStyleWidth)) {
        mCssStyle->mStyleWidth = NAN;
        markDirty();
        markChildrenDirty(true);
      }
    }

    inline float getStyleWidth() const {
      return mCssStyle->mStyleWidth;
    }

    inline void setStyleHeight(const float height) {
      if (mCssStyle->mStyleHeight != height) {
        mCssStyle->mStyleHeight = height;
        markDirty();
      }
    }

    inline float getStyleHeight() const {
      return mCssStyle->mStyleHeight;
    }

    inline void setMinWidth(const float minWidth, const bool updating) {
      if (mCssStyle->mMinWidth != minWidth) {
        mCssStyle->mMinWidth = minWidth;
        markDirty();
        if(updating) {
          markChildrenDirty(true);
        }
      }
    }

    inline float getMinWidth() const {
      return mCssStyle->mMinWidth;
    }

    inline void setMaxWidth(const float maxWidth, const bool updating) {
      if (mCssStyle->mMaxWidth != maxWidth) {
        mCssStyle->mMaxWidth = maxWidth;
        markDirty();
        if(updating) {
          markChildrenDirty(true);
        }
      }
    }

    inline float getMaxWidth() const {
      return mCssStyle->mMaxWidth;
    }

    inline void setMinHeight(const float minHeight) {
      if (mCssStyle->mMinHeight != minHeight) {
        mCssStyle->mMinHeight = minHeight;
        markDirty();
      }
    }

    inline float getMinHeight() const {
      return mCssStyle->mMinHeight;
    }

    inline void setMaxHeight(const float maxHeight) {
      if (mCssStyle->mMaxHeight != maxHeight) {
        mCssStyle->mMaxHeight = maxHeight;
        markDirty();
      }
    }

    inline float getMaxHeight() const {
      return mCssStyle->mMaxHeight;
    }


    /** ================================ flex-style =================================== **/

    inline void setFlexDirection(const WXCoreFlexDirection flexDirection, const bool updating) {
      if (mCssStyle->mFlexDirection != flexDirection) {
        mCssStyle->mFlexDirection = flexDirection;
        markDirty();
        if (updating) {
          for (auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
            (*it)->markDirty(false);
          }
        }
      }
    }

    inline WXCoreFlexDirection getFlexDirection() const {
      return mCssStyle->mFlexDirection;
    }

    inline void setFlexWrap(const WXCoreFlexWrap flexWrap) {
      if (mCssStyle->mFlexWrap != flexWrap) {
        mCssStyle->mFlexWrap = flexWrap;
        markDirty();
      }
    }

    inline WXCoreFlexWrap getFlexWrap() const {
      return mCssStyle->mFlexWrap;
    }

    inline void setJustifyContent(const WXCoreJustifyContent justifyContent) {
      if (mCssStyle->mJustifyContent != justifyContent) {
        mCssStyle->mJustifyContent = justifyContent;
      }
    }

    inline WXCoreJustifyContent getJustifyContent() const {
      return mCssStyle->mJustifyContent;
    }

    inline void setAlignItems(const WXCoreAlignItems alignItems) {
      if (mCssStyle->mAlignItems != alignItems) {
        mCssStyle->mAlignItems = alignItems;
        markDirty();
      }
    }

    inline WXCoreAlignItems getAlignItems() const {
      return mCssStyle->mAlignItems;
    }

    inline void setAlignSelf(const WXCoreAlignSelf alignSelf) {
      if (mCssStyle->mAlignSelf != alignSelf) {
        mCssStyle->mAlignSelf = alignSelf;
        markDirty();
      }
    }

    inline WXCoreAlignSelf getAlignSelf() const {
      return mCssStyle->mAlignSelf;
    }

    virtual void set_flex(const float flex) {
      if (mCssStyle->mFlexGrow != flex) {
        mCssStyle->mFlexGrow = flex;
        markDirty();
      }
    }

    inline float getFlex() const {
      return mCssStyle->mFlexGrow;
    }

    /** ================================ layout-result =================================== **/

    inline float getLayoutWidth() const {
      return mLayoutResult->mLayoutSize.width;
    }

    inline float getLayoutHeight() const {
      return mLayoutResult->mLayoutSize.height;
    }

    inline float getLayoutPositionTop() const {
      return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeTop);
    }

    inline float getLayoutPositionBottom() const {
      return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeBottom);
    }

    inline float getLayoutPositionLeft() const {
      return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeLeft);
    }

    inline float getLayoutPositionRight() const  {
      return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeRight);
    }

    inline bool hasNewLayout() const {
      return mHasNewLayout;
    }

    inline bool isDirty() const {
      return dirty;
    }

    inline void markDirty(const bool recursion = true) {
      if (!isDirty()) {
        dirty = true;
        if (getParent() != nullptr && recursion) {
          getParent()->markDirty();
        }
      }
    }
      
    void markAllDirty() {
      markDirty(false);
      for (WXCoreLayoutNode* c : mChildList) {
          c->markAllDirty();
      }
    }

    bool markChildrenDirty(const bool updatedNode = false) {
      bool ret = false;
      if(getChildCount() == 0){
        if(measureFunc!= nullptr){
          ret = true;
        }
      }
      else {
        //isnan(mCssStyle->mStyleWidth) XOR updatedNode
        if(isnan(mCssStyle->mStyleWidth) != updatedNode){
          for (auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
            ret = ((*it)->markChildrenDirty() || ret) ;
          }
        }
      }
      dirty = ret || dirty;
      return ret;
    }

    inline void setHasNewLayout(const bool hasNewLayout) {
      this->mHasNewLayout = hasNewLayout;
    }

    inline float getLargestMainSize() const {
      float largestSize = 0;
      for (WXCoreFlexLine *flexLine : mFlexLines) {
        largestSize = std::max(largestSize, flexLine->mMainSize);
      }
      return largestSize + sumPaddingBorderAlongAxis(this, isMainAxisHorizontal(this));
    }
      
    inline void rewriteLayoutResult(float left, float top, float width, float height) {
      if (mLayoutResult != nullptr) {
          mLayoutResult->mLayoutPosition.setPosition(kPositionEdgeLeft, left);
          mLayoutResult->mLayoutPosition.setPosition(kPositionEdgeTop, top);
          mLayoutResult->mLayoutPosition.setPosition(kPositionEdgeRight, left + width);
          mLayoutResult->mLayoutPosition.setPosition(kPositionEdgeBottom, top + height);
          mLayoutResult->mLayoutSize.width = width;
          mLayoutResult->mLayoutSize.height = height;
      }
    }
  };
}
#endif //WEEXCORE_FLEXLAYOUT_WXCORELAYOUTNODE_H
#endif
