/*
 * 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.
 */
package com.taobao.weex.ui.view.border;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.SparseIntArray;
import com.taobao.weex.dom.CSSShorthand;
import com.taobao.weex.dom.CSSShorthand.CORNER;
import com.taobao.weex.dom.CSSShorthand.EDGE;
import com.taobao.weex.utils.WXLogUtils;
import com.taobao.weex.utils.WXViewUtils;

import static com.taobao.weex.dom.CSSShorthand.CORNER.ALL;
import static com.taobao.weex.dom.CSSShorthand.CORNER.BORDER_BOTTOM_LEFT;
import static com.taobao.weex.dom.CSSShorthand.CORNER.BORDER_BOTTOM_RIGHT;
import static com.taobao.weex.dom.CSSShorthand.CORNER.BORDER_TOP_LEFT;
import static com.taobao.weex.dom.CSSShorthand.CORNER.BORDER_TOP_RIGHT;

/**
 * A subclass of
 * {@link Drawable} used for background of {@link com.taobao.weex.ui.component.WXComponent}.
 * It supports drawing background color and borders (including rounded borders) by providing a react
 * friendly API (setter for each of those properties). The implementation tries to allocate as few
 * objects as possible depending on which properties are set. E.g. for views with rounded
 * background/borders we allocate {@code mPathForBorderDrawn} and {@code mTempRectForBorderRadius}.
 * In case when view have a rectangular borders we allocate {@code mBorderWidthResult} and similar.
 * When only background color is set we won't allocate any extra/unnecessary objects.
 */
public class BorderDrawable extends Drawable {

  public static final int BORDER_TOP_LEFT_RADIUS = 0;
  public static final int BORDER_TOP_RIGHT_RADIUS = 1;
  public static final int BORDER_BOTTOM_RIGHT_RADIUS = 2;
  public static final int BORDER_BOTTOM_LEFT_RADIUS = 3;
  public static final int BORDER_RADIUS_ALL = 5;
  static final int DEFAULT_BORDER_COLOR = Color.BLACK;
  static final float DEFAULT_BORDER_WIDTH = 0;
  private static final BorderStyle DEFAULT_BORDER_STYLE = BorderStyle.SOLID;
  private static final String TAG = "Border";
  private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  private static BorderStyle[] sBorderStyle = BorderStyle.values();

  private
  @Nullable
  CSSShorthand<EDGE> mBorderWidth;
  private
  @Nullable
  CSSShorthand<CORNER> mBorderRadius;
  private
  @Nullable
  CSSShorthand<CORNER> mOverlappingBorderRadius;
  private
  @Nullable
  SparseIntArray mBorderColor;
  private
  @Nullable
  SparseIntArray mBorderStyle;

  private
  @Nullable
  Path mPathForBorderOutline;
  private boolean mNeedUpdatePath = false;
  private int mColor = Color.TRANSPARENT;
  /**
   * set background-image linear-gradient
   */
  private Shader mShader = null;
  private int mAlpha = 255;

  private TopLeftCorner mTopLeftCorner;
  private TopRightCorner mTopRightCorner;
  private BottomRightCorner mBottomRightCorner;
  private BottomLeftCorner mBottomLeftCorner;

  private final BorderEdge mBorderEdge = new BorderEdge();

  private RectF mRectBounds;

  public BorderDrawable() {
  }

  @Override
  public void draw(@NonNull Canvas canvas) {
    canvas.save();
    updateBorderOutline();
    //Shader uses alpha as well.
    mPaint.setAlpha(255);
    if (mPathForBorderOutline != null) {
      int useColor = WXViewUtils.multiplyColorAlpha(mColor, mAlpha);
      if (mShader != null) {
        mPaint.setShader(mShader);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawPath(mPathForBorderOutline, mPaint);
        mPaint.setShader(null);
      } else if ((useColor >>> 24) != 0) {
        mPaint.setColor(useColor);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawPath(mPathForBorderOutline, mPaint);
        mPaint.setShader(null);
      }
    }
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    drawBorders(canvas);
    mPaint.setShader(null);
    canvas.restore();
  }

  @Override
  protected void onBoundsChange(Rect bounds) {
    super.onBoundsChange(bounds);
    mNeedUpdatePath = true;
  }

  @Override
  public void setAlpha(int alpha) {
    if (alpha != mAlpha) {
      mAlpha = alpha;
      invalidateSelf();
    }
  }

  @Override
  public int getAlpha() {
    return mAlpha;
  }

  /**
   * Do not support Color Filter
   */
  @Override
  public void setColorFilter(ColorFilter cf) {

  }

  @Override
  public int getOpacity() {
    return mShader != null ? PixelFormat.OPAQUE :
            WXViewUtils.getOpacityFromColor(WXViewUtils.multiplyColorAlpha(mColor, mAlpha));
  }

  /* Android's elevation implementation requires this to be implemented to know where to draw the
 shadow. */
  @Override
  public void getOutline(@NonNull Outline outline) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      if (mPathForBorderOutline == null) {
        mNeedUpdatePath = true;
      }
      updateBorderOutline();
      outline.setConvexPath(mPathForBorderOutline);
    }
  }

  public void setBorderWidth(CSSShorthand.EDGE edge, float width) {
    if (mBorderWidth == null) {
      mBorderWidth = new CSSShorthand<>();
    }
    if (mBorderWidth.get(edge) != width) {
      mBorderWidth.set(edge, width);
      mNeedUpdatePath = true;
      invalidateSelf();
    }
  }

  float getBorderWidth(CSSShorthand.EDGE edge) {
    return mBorderWidth.get(edge);
  }

  public void setBorderRadius(CORNER position, float radius) {
    if (mBorderRadius == null) {
      mBorderRadius = new CSSShorthand<>();
    }
    if (mBorderRadius.get(position) != radius ||
        (position == ALL &&
            (radius != mBorderRadius.get(BORDER_TOP_LEFT) ||
            radius != mBorderRadius.get(BORDER_TOP_RIGHT) ||
            radius != mBorderRadius.get(BORDER_BOTTOM_RIGHT) ||
            radius != mBorderRadius.get(BORDER_BOTTOM_LEFT)))) {
      mBorderRadius.set(position, radius);
      mNeedUpdatePath = true;
      invalidateSelf();
    }
  }

  public
  @NonNull
  float[] getBorderRadius(RectF borderBox) {
    prepareBorderRadius(borderBox);
    if (mOverlappingBorderRadius == null) {
      mOverlappingBorderRadius = new CSSShorthand<>();
    }
    float topLeftRadius = mOverlappingBorderRadius.get(BORDER_TOP_LEFT);
    float topRightRadius = mOverlappingBorderRadius.get(BORDER_TOP_RIGHT);
    float bottomRightRadius = mOverlappingBorderRadius.get(BORDER_BOTTOM_RIGHT);
    float bottomLeftRadius = mOverlappingBorderRadius.get(BORDER_BOTTOM_LEFT);
    return new float[]{topLeftRadius, topLeftRadius,
            topRightRadius, topRightRadius,
            bottomRightRadius, bottomRightRadius,
            bottomLeftRadius, bottomLeftRadius};
  }

  public
  @NonNull
  float[] getBorderInnerRadius(RectF borderBox) {
    prepareBorderRadius(borderBox);
    if (mOverlappingBorderRadius == null) {
      mOverlappingBorderRadius = new CSSShorthand<>();
    }
    float topLeftRadius = mOverlappingBorderRadius.get(BORDER_TOP_LEFT);
    float topRightRadius = mOverlappingBorderRadius.get(BORDER_TOP_RIGHT);
    float bottomRightRadius = mOverlappingBorderRadius.get(BORDER_BOTTOM_RIGHT);
    float bottomLeftRadius = mOverlappingBorderRadius.get(BORDER_BOTTOM_LEFT);
    if (null != mBorderWidth) {
      topLeftRadius = Math.max(topLeftRadius - mBorderWidth.get(EDGE.TOP), 0);
      topRightRadius = Math.max(topRightRadius - mBorderWidth.get(EDGE.TOP), 0);
      bottomRightRadius = Math.max(bottomRightRadius - mBorderWidth.get(EDGE.BOTTOM), 0);
      bottomLeftRadius = Math.max(bottomLeftRadius - mBorderWidth.get(EDGE.BOTTOM), 0);
    }
    return new float[] {topLeftRadius, topLeftRadius,
        topRightRadius, topRightRadius,
        bottomRightRadius, bottomRightRadius,
        bottomLeftRadius, bottomLeftRadius};
  }

  public void setBorderColor(CSSShorthand.EDGE edge, int color) {
    if (mBorderColor == null) {
      mBorderColor = new SparseIntArray(5);
      mBorderColor.put(CSSShorthand.EDGE.ALL.ordinal(), DEFAULT_BORDER_COLOR);
    }
    if (getBorderColor(edge) != color) {
      BorderUtil.updateSparseArray(mBorderColor, edge.ordinal(), color);
      invalidateSelf();
    }
  }

  int getBorderColor(CSSShorthand.EDGE edge) {
    return BorderUtil.fetchFromSparseArray(mBorderColor, edge.ordinal(), DEFAULT_BORDER_COLOR);
  }

  public void setBorderStyle(CSSShorthand.EDGE edge, @NonNull String style) {
    if (mBorderStyle == null) {
      mBorderStyle = new SparseIntArray(5);
      mBorderStyle.put(CSSShorthand.EDGE.ALL.ordinal(), DEFAULT_BORDER_STYLE.ordinal());
    }
    try {
      int borderStyle = BorderStyle.valueOf(style.toUpperCase(Locale.US)).ordinal();
      if (getBorderStyle(edge) != borderStyle) {
        BorderUtil.updateSparseArray(mBorderStyle, edge.ordinal(), borderStyle);
        invalidateSelf();
      }
    } catch (IllegalArgumentException e) {
      WXLogUtils.e(TAG, WXLogUtils.getStackTrace(e));
    }
  }

  int getBorderStyle(CSSShorthand.EDGE edge) {
    return BorderUtil.fetchFromSparseArray(mBorderStyle, edge.ordinal(), BorderStyle.SOLID.ordinal());
  }

  public int getColor() {
    return mColor;
  }

  public void setColor(int color) {
    mColor = color;
    invalidateSelf();
  }

  public void setImage(Shader shader) {
    mShader = shader;
    invalidateSelf();
  }

  public boolean hasImage() {
    return mShader != null;
  }

  public boolean isRounded() {
    return mBorderRadius != null &&
            (mBorderRadius.get(BORDER_TOP_LEFT) != 0 ||
                mBorderRadius.get(BORDER_TOP_RIGHT) != 0 ||
                mBorderRadius.get(BORDER_BOTTOM_RIGHT) != 0 ||
                mBorderRadius.get(BORDER_BOTTOM_LEFT) != 0);
  }

  public
  @NonNull
  Path getContentPath(@NonNull RectF borderBox) {
    Path contentClip = new Path();
    prepareBorderPath(0, 0, 0, 0, borderBox, contentClip);
    return contentClip;
  }

  private void updateBorderOutline() {
    if (mNeedUpdatePath) {
      mNeedUpdatePath = false;
      if (mPathForBorderOutline == null) {
        mPathForBorderOutline = new Path();
      }
      mPathForBorderOutline.reset();
      prepareBorderPath(0, 0, 0, 0, new RectF(getBounds()), mPathForBorderOutline);
    }
  }

  private void prepareBorderPath(int topPadding,
                                 int rightPadding,
                                 int bottomPadding,
                                 int leftPadding,
                                 @NonNull RectF rectF,
                                 @NonNull Path path) {
    if (mBorderRadius != null) {
      prepareBorderRadius(rectF);
      if (mOverlappingBorderRadius == null) {
        mOverlappingBorderRadius = new CSSShorthand<>();
      }
      float topLeftRadius = mOverlappingBorderRadius.get(BORDER_TOP_LEFT);
      float topRightRadius = mOverlappingBorderRadius.get(BORDER_TOP_RIGHT);
      float bottomRightRadius = mOverlappingBorderRadius.get(BORDER_BOTTOM_RIGHT);
      float bottomLeftRadius = mOverlappingBorderRadius.get(BORDER_BOTTOM_LEFT);
      path.addRoundRect(
              rectF,
              new float[]{
                      topLeftRadius - leftPadding,
                      topLeftRadius - topPadding,
                      topRightRadius - rightPadding,
                      topRightRadius - topPadding,
                      bottomRightRadius - rightPadding,
                      bottomRightRadius - bottomPadding,
                      bottomLeftRadius - leftPadding,
                      bottomLeftRadius - bottomPadding
              },
              Path.Direction.CW);
    } else {
      path.addRect(rectF, Path.Direction.CW);
    }
  }

  /**
   * Process overlapping curve according to https://www.w3.org/TR/css3-background/#corner-overlap .
   */
  private void prepareBorderRadius(@NonNull RectF borderBox) {
    if (mBorderRadius != null) {
      float factor = getScaleFactor(borderBox);
      if (mOverlappingBorderRadius == null) {
        mOverlappingBorderRadius = new CSSShorthand<>();
      }
      if (!Float.isNaN(factor) && factor < 1) {
        mOverlappingBorderRadius.set(BORDER_TOP_LEFT,
            mBorderRadius.get(BORDER_TOP_LEFT) * factor);
        mOverlappingBorderRadius.set(BORDER_TOP_RIGHT,
            mBorderRadius.get(BORDER_TOP_RIGHT) * factor);
        mOverlappingBorderRadius.set(BORDER_BOTTOM_RIGHT,
            mBorderRadius.get(BORDER_BOTTOM_RIGHT) * factor);
        mOverlappingBorderRadius.set(BORDER_BOTTOM_LEFT,
            mBorderRadius.get(BORDER_BOTTOM_LEFT) * factor);
      } else {
        mOverlappingBorderRadius.set(BORDER_TOP_LEFT,
            mBorderRadius.get(BORDER_TOP_LEFT));
        mOverlappingBorderRadius.set(BORDER_TOP_RIGHT,
            mBorderRadius.get(BORDER_TOP_RIGHT));
        mOverlappingBorderRadius.set(BORDER_BOTTOM_RIGHT,
            mBorderRadius.get(BORDER_BOTTOM_RIGHT));
        mOverlappingBorderRadius.set(BORDER_BOTTOM_LEFT,
            mBorderRadius.get(BORDER_BOTTOM_LEFT));
      }
    }
  }

  private float getScaleFactor(@NonNull RectF borderBox) {
    final float topRadius = mBorderRadius.get(BORDER_TOP_LEFT)
            + mBorderRadius.get(BORDER_TOP_RIGHT);
    final float rightRadius = mBorderRadius.get(BORDER_TOP_RIGHT)
            + mBorderRadius.get(BORDER_BOTTOM_RIGHT);
    final float bottomRadius = mBorderRadius.get(BORDER_BOTTOM_RIGHT)
            + mBorderRadius.get(BORDER_BOTTOM_LEFT);
    final float leftRadius = mBorderRadius.get(BORDER_BOTTOM_LEFT)
            + mBorderRadius.get(BORDER_TOP_LEFT);
    List<Float> factors = new ArrayList<>(4);
    updateFactor(factors, borderBox.width(), topRadius);
    updateFactor(factors, borderBox.height(), rightRadius);
    updateFactor(factors, borderBox.width(), bottomRadius);
    updateFactor(factors, borderBox.height(), leftRadius);
    float factor;
    if (factors.isEmpty()) {
      factor = Float.NaN;
    } else {
      factor = Collections.min(factors);
    }
    return factor;
  }

  private void updateFactor(@NonNull List<Float> list, float numerator, float denominator) {
    if (denominator != 0) {
      list.add(numerator / denominator);
    }
  }

  private void drawBorders(Canvas canvas) {
    if (mRectBounds == null) {
      mRectBounds = new RectF(getBounds());
    } else {
      mRectBounds.set(getBounds());
    }

    if (mBorderWidth == null)
      return;

    final float leftBorderWidth = mBorderWidth.get(EDGE.LEFT);
    final float topBorderWidth = mBorderWidth.get(EDGE.TOP);
    final float bottomBorderWidth = mBorderWidth.get(EDGE.BOTTOM);
    final float rightBorderWidth = mBorderWidth.get(EDGE.RIGHT);

    if (mTopLeftCorner == null) {
      mTopLeftCorner = new TopLeftCorner();
    }
    mTopLeftCorner.set(getBorderRadius(BORDER_TOP_LEFT), leftBorderWidth, topBorderWidth, mRectBounds);
    if (mTopRightCorner == null) {
      mTopRightCorner = new TopRightCorner();
    }
    mTopRightCorner.set(getBorderRadius(BORDER_TOP_RIGHT), topBorderWidth, rightBorderWidth, mRectBounds);
    if (mBottomRightCorner == null) {
      mBottomRightCorner = new BottomRightCorner();
    }
    mBottomRightCorner.set(getBorderRadius(BORDER_BOTTOM_RIGHT), rightBorderWidth, bottomBorderWidth, mRectBounds);
    if (mBottomLeftCorner == null) {
      mBottomLeftCorner = new BottomLeftCorner();
    }
    mBottomLeftCorner.set(getBorderRadius(BORDER_BOTTOM_LEFT), bottomBorderWidth, leftBorderWidth, mRectBounds);

    drawOneSide(canvas, mBorderEdge.set(mTopLeftCorner, mTopRightCorner, topBorderWidth, EDGE.TOP));
    drawOneSide(canvas, mBorderEdge.set(mTopRightCorner, mBottomRightCorner, rightBorderWidth, EDGE.RIGHT));
    drawOneSide(canvas, mBorderEdge.set(mBottomRightCorner, mBottomLeftCorner, bottomBorderWidth, EDGE.BOTTOM));
    drawOneSide(canvas, mBorderEdge.set(mBottomLeftCorner, mTopLeftCorner, leftBorderWidth, EDGE.LEFT));
  }

  private float getBorderRadius(CORNER position) {
    if (null != mOverlappingBorderRadius) {
      return mOverlappingBorderRadius.get(position);
    } else {
      return 0.0f;
    }
  }

  private void drawOneSide(Canvas canvas, @NonNull BorderEdge borderEdge) {
    if (0 != borderEdge.getBorderWidth()) {
      preparePaint(borderEdge.getEdge());
      borderEdge.drawEdge(canvas, mPaint);
    }
  }

  private void preparePaint(CSSShorthand.EDGE edge) {
    final float borderWidth = mBorderWidth.get(edge);
    final int color = WXViewUtils.multiplyColorAlpha(getBorderColor(edge), mAlpha);
    final BorderStyle borderStyle = sBorderStyle[getBorderStyle(edge)];
    final Shader shader = borderStyle.getLineShader(borderWidth, color, edge);
    mPaint.setShader(shader);
    mPaint.setColor(color);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
  }
}
