/*
 * 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.
 */
/**
 * Copyright (c) 2014, Facebook, Inc. All rights reserved. <p/> This source code is licensed under
 * the BSD-cssstyle 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.taobao.weex.dom.flex;

//import javax.annotation.Nullable;

import android.support.annotation.NonNull;

import com.taobao.weex.WXEnvironment;
import com.taobao.weex.utils.WXLogUtils;

import java.util.ArrayList;

import static com.taobao.weex.dom.flex.CSSLayout.DIMENSION_HEIGHT;
import static com.taobao.weex.dom.flex.CSSLayout.DIMENSION_WIDTH;
import static com.taobao.weex.dom.flex.CSSLayout.POSITION_BOTTOM;
import static com.taobao.weex.dom.flex.CSSLayout.POSITION_LEFT;
import static com.taobao.weex.dom.flex.CSSLayout.POSITION_RIGHT;
import static com.taobao.weex.dom.flex.CSSLayout.POSITION_TOP;

//import com.facebook.infer.annotation.Assertions;

/**
 * A CSS Node. It has a cssstyle object you can manipulate at {@link #cssstyle}. After calling
 * {@link #calculateLayout(CSSLayoutContext)}, {@link #csslayout} will be filled with the results of
 * the csslayout.
 */
public class CSSNode {

  // VisibleForTesting
  /*package*/public final CSSStyle cssstyle = new CSSStyle();
  /*package*/ public final CSSLayout csslayout = new CSSLayout();
  /*package*/ final CachedCSSLayout lastLayout = new CachedCSSLayout();
  public int lineIndex = 0;
  /*package*/ CSSNode nextAbsoluteChild;
  /*package*/ CSSNode nextFlexChild;
  private ArrayList<CSSNode> mChildren;
  private CSSNode mParent;
  private MeasureFunction mMeasureFunction = null;
  private LayoutState mLayoutState = LayoutState.DIRTY;
  private boolean mShow = true;

  private boolean mIsLayoutChanged = true;

  public boolean isShow() {
    return mShow;
  }

  public void setVisible(boolean isShow) {
    if (!mShow && isShow) {
      mLayoutState = LayoutState.UP_TO_DATE;
    }
    mShow = isShow;
    dirty();
  }

  public void markLayoutStateUpdated(){
     this.mLayoutState = LayoutState.UP_TO_DATE;
  }

  /**
   * whether layout changed when {@link #updateLastLayout(CSSLayout)} invoked last time.
   * @return
     */
  public boolean isLayoutChanged(){
    return mIsLayoutChanged;
  }

  /**
   * must invoke after every layout finished,even nothing changed.
   * @param newLayout
   * @return
     */
  public boolean updateLastLayout(CSSLayout newLayout){
    mIsLayoutChanged = !lastLayout.equals(newLayout);
    if(mIsLayoutChanged) {
      lastLayout.copy(newLayout);
    }
    return mIsLayoutChanged;
  }

  public int getChildCount() {
    return mChildren == null ? 0 : mChildren.size();
  }

  public CSSNode getChildAt(int i) {
    //    Assertions.assertNotNull(mChildren);
    return mChildren.get(i);
  }

  public void addChildAt(CSSNode child, int i) {
    if (child.mParent != null) {
      throw new IllegalStateException("Child already has a parent, it must be removed first.");
    }
    if (mChildren == null) {
      // 4 is kinda arbitrary, but the default of 10 seems really high for an average View.
      mChildren = new ArrayList<CSSNode>(4);
    }

    mChildren.add(i, child);
    child.mParent = this;
    dirty();
  }

  public CSSNode removeChildAt(int i) {
    //    Assertions.assertNotNull(mChildren);
    CSSNode removed = mChildren.remove(i);
    removed.mParent = null;
    dirty();
    return removed;
  }

  public void setParentNull() {
    mParent = null;
  }

  public CSSNode getParent() {
    return mParent;
  }

  /**
   * @return the index of the given child, or -1 if the child doesn't exist in this node.
   */
  public int indexOf(CSSNode child) {
    //    Assertions.assertNotNull(mChildren);
    return mChildren.indexOf(child);
  }

  public void setMeasureFunction(MeasureFunction measureFunction) {
    if (mMeasureFunction != measureFunction) {
      mMeasureFunction = measureFunction;
      dirty();
    }
  }

  /*package*/ MeasureOutput measure(MeasureOutput measureOutput, float width) {
    if (!isMeasureDefined()) {
      throw new RuntimeException("Measure function isn't defined!");
    }
    measureOutput.height = CSSConstants.UNDEFINED;
    measureOutput.width = CSSConstants.UNDEFINED;
    if (mMeasureFunction != null) {
      mMeasureFunction.measure(this, width, measureOutput);
    }
    //    Assertions.assertNotNull(mMeasureFunction).measure(this, width, measureOutput);
    return measureOutput;
  }

  public boolean isMeasureDefined() {
    return mMeasureFunction != null;
  }

  /**
   * Performs the actual csslayout and saves the results in {@link #csslayout}
   */
  public void calculateLayout(CSSLayoutContext layoutContext) {
    csslayout.resetResult();
    LayoutEngine.layoutNode(layoutContext, this, CSSConstants.UNDEFINED, null);
  }

  /**
   * See {@link LayoutState#DIRTY}.
   */
  protected boolean isDirty() {
    return mLayoutState == LayoutState.DIRTY;
  }

  protected void dirty() {
    if (mLayoutState == LayoutState.DIRTY) {
      return;
    } else if (mLayoutState == LayoutState.HAS_NEW_LAYOUT) {
      if(WXEnvironment.isApkDebugable()){
          WXLogUtils.d("Previous csslayout was ignored! markLayoutSeen() never called");
      }
      markLayoutSeen();
    }

    mLayoutState = LayoutState.DIRTY;

    if (mParent != null && !mParent.isDirty()) {
      mParent.dirty();
    }
  }

  /*package*/ void markHasNewLayout() {
    mLayoutState = LayoutState.HAS_NEW_LAYOUT;
  }

  /**
   * Tells the node that the current values in {@link #csslayout} have been seen. Subsequent calls
   * to {@link #hasNewLayout()} will return false until this node is laid out with new parameters.
   * You must call this each time the csslayout is generated if the node has a new csslayout.
   */
  public void markLayoutSeen() {
    if (!hasNewLayout()) {
      throw new IllegalStateException("Expected node to have a new csslayout to be seen!");
    }

    mLayoutState = LayoutState.UP_TO_DATE;
  }

  /**
   * See {@link LayoutState#HAS_NEW_LAYOUT}.
   */
  public boolean hasNewLayout() {
    return mLayoutState == LayoutState.HAS_NEW_LAYOUT;
  }

  private void toStringWithIndentation(StringBuilder result, int level) {
    // Spaces and tabs are dropped by IntelliJ logcat integration, so rely on __ instead.
    StringBuilder indentation = new StringBuilder();
    for (int i = 0; i < level; ++i) {
      indentation.append("__");
    }

    result.append(indentation.toString());
    result.append(csslayout.toString());
    result.append(cssstyle.toString());

    if (getChildCount() == 0) {
      return;
    }

    result.append(", children: [\n");
    for (int i = 0; i < getChildCount(); i++) {
      getChildAt(i).toStringWithIndentation(result, level + 1);
      result.append("\n");
    }
    result.append(indentation + "]");
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    this.toStringWithIndentation(sb, 0);
    return sb.toString();
  }

  protected boolean valuesEqual(float f1, float f2) {
    return FloatUtil.floatsEqual(f1, f2);
  }

  /**
   * Get this node's direction, as defined in the cssstyle.
   */
  public CSSDirection getStyleDirection() {
    return cssstyle.direction;
  }

  public void setDirection(CSSDirection direction) {
    if (cssstyle.direction != direction) {
      cssstyle.direction = direction;
      dirty();
    }
  }

  /**
   * Get this node's flex direction, as defined by cssstyle.
   */
  public CSSFlexDirection getFlexDirection() {
    return cssstyle.flexDirection;
  }

  public void setFlexDirection(CSSFlexDirection flexDirection) {
    if (cssstyle.flexDirection != flexDirection) {
      cssstyle.flexDirection = flexDirection;
      dirty();
    }
  }

  /**
   * Get this node's justify content, as defined by cssstyle.
   */
  public CSSJustify getJustifyContent() {
    return cssstyle.justifyContent;
  }

  public void setJustifyContent(CSSJustify justifyContent) {
    if (cssstyle.justifyContent != justifyContent) {
      cssstyle.justifyContent = justifyContent;
      dirty();
    }
  }

  /**
   * Get this node's align items, as defined by cssstyle.
   */
  public CSSAlign getAlignItems() {
    return cssstyle.alignItems;
  }

  public void setAlignItems(CSSAlign alignItems) {
    if (cssstyle.alignItems != alignItems) {
      cssstyle.alignItems = alignItems;
      dirty();
    }
  }

  /**
   * Get this node's align items, as defined by cssstyle.
   */
  public CSSAlign getAlignSelf() {
    return cssstyle.alignSelf;
  }

  public void setAlignSelf(CSSAlign alignSelf) {
    if (cssstyle.alignSelf != alignSelf) {
      cssstyle.alignSelf = alignSelf;
      dirty();
    }
  }

  /**
   * Get this node's position type, as defined by cssstyle.
   */
  public CSSPositionType getPositionType() {
    return cssstyle.positionType;
  }

  public void setPositionType(CSSPositionType positionType) {
    if (cssstyle.positionType != positionType) {
      cssstyle.positionType = positionType;
      dirty();
    }
  }

  public void setWrap(CSSWrap flexWrap) {
    if (cssstyle.flexWrap != flexWrap) {
      cssstyle.flexWrap = flexWrap;
      dirty();
    }
  }

  /**
   * Get this node's flex, as defined by cssstyle.
   */
  public float getFlex() {
    return cssstyle.flex;
  }

  public void setFlex(float flex) {
    if (!valuesEqual(cssstyle.flex, flex)) {
      cssstyle.flex = flex;
      dirty();
    }
  }

  /**
   * Get this node's margin, as defined by cssstyle + default margin.
   */
  public @NonNull Spacing getMargin() {
    return cssstyle.margin;
  }

  public void setMargin(int spacingType, float margin) {
    if (cssstyle.margin.set(spacingType, margin)) {
      dirty();
    }
  }

  public void setMinWidth(float minWidth) {
    if (!valuesEqual(cssstyle.minWidth, minWidth)) {
      cssstyle.minWidth = minWidth;
      dirty();
    }
  }

  public void setMaxWidth(float maxWidth) {
    if (!valuesEqual(cssstyle.maxWidth, maxWidth)) {
      cssstyle.maxWidth = maxWidth;
      dirty();
    }
  }

  public void setMinHeight(float minHeight) {
    if (!valuesEqual(cssstyle.minHeight, minHeight)) {
      cssstyle.minHeight = minHeight;
      dirty();
    }
  }

  public void setMaxHeight(float maxHeight) {
    if (!valuesEqual(cssstyle.maxHeight, maxHeight)) {
      cssstyle.maxHeight = maxHeight;
      dirty();
    }
  }

  /**
   * Get this node's padding, as defined by cssstyle + default padding.
   */
  public @NonNull Spacing getPadding() {
    return cssstyle.padding;
  }

  public void setPadding(int spacingType, float padding) {
    if (cssstyle.padding.set(spacingType, padding)) {
      dirty();
    }
  }

  /**
   * Get this node's border, as defined by cssstyle.
   */
  public @NonNull Spacing getBorder() {
    return cssstyle.border;
  }

  public void setBorder(int spacingType, float border) {
    if (cssstyle.border.set(spacingType, border)) {
      dirty();
    }
  }

  /**
   * Get this node's position top, as defined by cssstyle.
   */
  public float getPositionTop() {
    return cssstyle.position[POSITION_TOP];
  }

  public void setPositionTop(float positionTop) {
    if (!valuesEqual(cssstyle.position[POSITION_TOP], positionTop)) {
      cssstyle.position[POSITION_TOP] = positionTop;
      dirty();
    }
  }

  /**
   * Get this node's position bottom, as defined by cssstyle.
   */
  public float getPositionBottom() {
    return cssstyle.position[POSITION_BOTTOM];
  }

  public void setPositionBottom(float positionBottom) {
    if (!valuesEqual(cssstyle.position[POSITION_BOTTOM], positionBottom)) {
      cssstyle.position[POSITION_BOTTOM] = positionBottom;
      dirty();
    }
  }

  /**
   * Get this node's position left, as defined by cssstyle.
   */
  public float getPositionLeft() {
    return cssstyle.position[POSITION_LEFT];
  }

  public void setPositionLeft(float positionLeft) {
    if (!valuesEqual(cssstyle.position[POSITION_LEFT], positionLeft)) {
      cssstyle.position[POSITION_LEFT] = positionLeft;
      dirty();
    }
  }

  /**
   * Get this node's position right, as defined by cssstyle.
   */
  public float getPositionRight() {
    return cssstyle.position[POSITION_RIGHT];
  }

  public void setPositionRight(float positionRight) {
    if (!valuesEqual(cssstyle.position[POSITION_RIGHT], positionRight)) {
      cssstyle.position[POSITION_RIGHT] = positionRight;
      dirty();
    }
  }

  /**
   * Get this node's width, as defined in the cssstyle.
   */
  public float getStyleWidth() {
    return cssstyle.dimensions[DIMENSION_WIDTH];
  }

  public void setStyleWidth(float width) {
    if (!valuesEqual(cssstyle.dimensions[DIMENSION_WIDTH], width)) {
      cssstyle.dimensions[DIMENSION_WIDTH] = width;
      dirty();
    }
  }

  /**
   * Get this node's height, as defined in the cssstyle.
   */
  public float getStyleHeight() {
    return cssstyle.dimensions[DIMENSION_HEIGHT];
  }

  public void setStyleHeight(float height) {
    if (!valuesEqual(cssstyle.dimensions[DIMENSION_HEIGHT], height)) {
      cssstyle.dimensions[DIMENSION_HEIGHT] = height;
      dirty();
    }
  }

  public float getLayoutX() {
    return csslayout.position[POSITION_LEFT];
  }

  public void setLayoutX(float x) {
    csslayout.position[POSITION_LEFT] = x;
  }

  public float getLayoutY() {
    return csslayout.position[POSITION_TOP];
  }

  public void setLayoutY(float y) {
    csslayout.position[POSITION_TOP] = y;
  }

  public float getLayoutWidth() {
    return csslayout.dimensions[DIMENSION_WIDTH];
  }

  public void setLayoutWidth(float width) {
    csslayout.dimensions[DIMENSION_WIDTH] = width;
  }

  public float getLayoutHeight() {
    return csslayout.dimensions[DIMENSION_HEIGHT];
  }

  public void setLayoutHeight(float height) {
    csslayout.dimensions[DIMENSION_HEIGHT] = height;
  }

  public CSSDirection getLayoutDirection() {
    return csslayout.direction;
  }

  /**
   * Set a default padding (left/top/right/bottom) for this node.
   */
  public void setDefaultPadding(int spacingType, float padding) {
    if (cssstyle.padding.setDefault(spacingType, padding)) {
      dirty();
    }
  }

  /**
   * Resets this instance to its default state. This method is meant to be used when recycling
   * {@link CSSNode} instances.
   */
  public void reset() {
    if (mParent != null || (mChildren != null && mChildren.size() > 0)) {
      throw new IllegalStateException("You should not reset an attached CSSNode");
    }

    cssstyle.reset();
    csslayout.resetResult();
    lineIndex = 0;
    mLayoutState = LayoutState.DIRTY;
  }

  private static enum LayoutState {
    /**
     * Some property of this node or its children has changes and the current values in {@link
     * #csslayout} are not valid.
     */
    DIRTY,

    /**
     * This node has a new csslayout relative to the last time {@link #markLayoutSeen()} was
     * called.
     */
    HAS_NEW_LAYOUT,

    /**
     * {@link #csslayout} is valid for the node's properties and this csslayout has been marked as
     * having been seen.
     */
    UP_TO_DATE,
  }

  public static interface MeasureFunction {

    /**
     * Should measure the given node and put the result in the given MeasureOutput.
     * NB: measure is NOT guaranteed to be threadsafe/re-entrant safe!
     */
    public void measure(CSSNode node, float width, MeasureOutput measureOutput);
  }

  public float getCSSLayoutHeight() {
    return csslayout.dimensions[CSSLayout.DIMENSION_HEIGHT];
  }

  public float getCSSLayoutWidth() {
    return csslayout.dimensions[CSSLayout.DIMENSION_WIDTH];
  }

  public float getCSSLayoutTop() {
    return csslayout.position[CSSLayout.POSITION_TOP];
  }

  public float getCSSLayoutBottom() {
    return csslayout.position[CSSLayout.POSITION_BOTTOM];
  }

  public float getCSSLayoutLeft() {
    return csslayout.position[CSSLayout.POSITION_LEFT];
  }

  public float getCSSLayoutRight() {
    return csslayout.position[CSSLayout.POSITION_RIGHT];
  }
}
