/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

package com.facebook.react.flat;

import javax.annotation.Nullable;

import com.facebook.csslayout.CSSNode;
import com.facebook.csslayout.CSSNodeAPI;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.ReactShadowNode;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.ViewManager;

/* package */ final class NativeViewWrapper extends FlatShadowNode implements AndroidView {

  @Nullable private final ReactShadowNode mReactShadowNode;
  private final boolean mNeedsCustomLayoutForChildren;
  private boolean mPaddingChanged = false;
  private boolean mForceMountGrandChildrenToView;

  /* package */ NativeViewWrapper(ViewManager viewManager) {
    ReactShadowNode reactShadowNode = viewManager.createShadowNodeInstance();
    if (reactShadowNode instanceof CSSNodeAPI.MeasureFunction) {
      mReactShadowNode = reactShadowNode;
      setMeasureFunction((CSSNodeAPI.MeasureFunction) reactShadowNode);
    } else {
      mReactShadowNode = null;
    }

    if (viewManager instanceof ViewGroupManager) {
      ViewGroupManager viewGroupManager = (ViewGroupManager) viewManager;
      mNeedsCustomLayoutForChildren = viewGroupManager.needsCustomLayoutForChildren();
      mForceMountGrandChildrenToView = viewGroupManager.shouldPromoteGrandchildren();
    } else {
      mNeedsCustomLayoutForChildren = false;
    }

    forceMountToView();
    forceMountChildrenToView();
  }

  @Override
  public boolean needsCustomLayoutForChildren() {
    return mNeedsCustomLayoutForChildren;
  }

  @Override
  public boolean isPaddingChanged() {
    return mPaddingChanged;
  }

  @Override
  public void resetPaddingChanged() {
    mPaddingChanged = false;
  }

  @Override
  public void setBackgroundColor(int backgroundColor) {
    // suppress, this is handled by a ViewManager
  }

  @Override
  public void setThemedContext(ThemedReactContext themedContext) {
    super.setThemedContext(themedContext);

    if (mReactShadowNode != null) {
      mReactShadowNode.setThemedContext(themedContext);
    }
  }

  @Override
  /* package*/ void handleUpdateProperties(ReactStylesDiffMap styles) {
    if (mReactShadowNode != null) {
      mReactShadowNode.updateProperties(styles);
    }
  }

  @Override
  public void addChildAt(CSSNode child, int i) {
    super.addChildAt(child, i);
    if (mForceMountGrandChildrenToView && child instanceof FlatShadowNode) {
      ((FlatShadowNode) child).forceMountChildrenToView();
    }
  }

  @Override
  public void setPadding(int spacingType, float padding) {
    if (getPadding().set(spacingType, padding)) {
      mPaddingChanged = true;
      dirty();
    }
  }
}

@@ -618,16 +618,74 @@
 ontext;%0A
+import com.facebook.react.uimanager.UIViewOperationQueue;%0A
 import c
@@ -2270,24 +2270,204 @@
 anager%0A  %7D%0A%0A
+  @Override%0A  public void setReactTag(int reactTag) %7B%0A    super.setReactTag(reactTag);%0A    if (mReactShadowNode != null) %7B%0A      mReactShadowNode.setReactTag(reactTag);%0A    %7D%0A  %7D%0A%0A
   @Override%0A
@@ -3275,11 +3275,282 @@
    %7D%0A  %7D
+%0A%0A  @Override%0A  public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) %7B%0A    if (mReactShadowNode != null && mReactShadowNode.hasUnseenUpdates()) %7B%0A      mReactShadowNode.onCollectExtraUpdates(uiViewOperationQueue);%0A      markUpdateSeen();%0A    %7D%0A  %7D
 %0A%7D%0A

Add Dependency Injection, nodes support for RN/Components integration