/*
 * 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.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.graphics.drawable.shapes.Shape;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.widget.ImageView;

public class ImageDrawable extends PaintDrawable {

  public static Drawable createImageDrawable(@Nullable Drawable original,
                                             @NonNull ImageView.ScaleType scaleType,
                                             @Nullable float[] borderRadius,
                                             int vWidth,
                                             int vHeight,
                                             boolean gif) {
    Bitmap bm;
    if (!gif && vWidth > 0 && vHeight > 0) {
      if (original instanceof BitmapDrawable &&
              (bm = ((BitmapDrawable) original).getBitmap()) != null) {
        ImageDrawable imageDrawable;
        imageDrawable = new ImageDrawable();
        imageDrawable.bitmapWidth = bm.getWidth();
        imageDrawable.bitmapHeight = bm.getHeight();
        BitmapShader bitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        updateShaderAndSize(scaleType, vWidth, vHeight, imageDrawable, bitmapShader);
        imageDrawable.getPaint().setShader(bitmapShader);
        return imageDrawable;
      } else if (original instanceof ImageDrawable) {
        ImageDrawable imageDrawable = (ImageDrawable) original;
        if (imageDrawable.getPaint() != null &&
                imageDrawable.getPaint().getShader() instanceof BitmapShader) {
          BitmapShader bitmapShader = (BitmapShader) imageDrawable.getPaint().getShader();
          updateShaderAndSize(scaleType, vWidth, vHeight, imageDrawable, bitmapShader);
          return imageDrawable;
        }
      }
    }
    return original;
  }

  private static void updateShaderAndSize(@NonNull ImageView.ScaleType scaleType, int vWidth, int vHeight, ImageDrawable imageDrawable, BitmapShader bitmapShader) {
    Matrix matrix = createShaderMatrix(scaleType, vWidth, vHeight,
            imageDrawable.bitmapWidth,
            imageDrawable.bitmapHeight);
    int intrinsicWidth = vWidth, intrinsicHeight = vHeight;
    if (scaleType == ImageView.ScaleType.FIT_CENTER) {
      RectF bitmapRect = new RectF(0, 0, imageDrawable.bitmapWidth, imageDrawable.bitmapHeight), contentRect = new RectF();
      matrix.mapRect(contentRect, bitmapRect);
      intrinsicWidth = (int) contentRect.width();
      intrinsicHeight = (int) contentRect.height();
      matrix = createShaderMatrix(scaleType, intrinsicWidth, intrinsicHeight, imageDrawable
              .bitmapWidth, imageDrawable.bitmapHeight);
    }
    imageDrawable.setIntrinsicWidth(intrinsicWidth);
    imageDrawable.setIntrinsicHeight(intrinsicHeight);
    bitmapShader.setLocalMatrix(matrix);
  }

  @NonNull
  private static Matrix createShaderMatrix(@NonNull ImageView.ScaleType scaleType, int vWidth,
                                           int vHeight, int bmWidth, int bmHeight) {
    float scale, translateX = 0, translateY = 0;

    if (bmWidth * vHeight > bmHeight * vWidth) {
      scale = vHeight / (float) bmHeight;
      translateX = (vWidth - bmWidth * scale) * 0.5f;
    } else {
      scale = vWidth / (float) bmWidth;
      translateY = (vHeight - bmHeight * scale) * 0.5f;
    }

    Matrix mMatrix = new Matrix();
    if (scaleType == ImageView.ScaleType.FIT_XY) {
      mMatrix.setScale(vWidth / (float) bmWidth, vHeight / (float) bmHeight);
    } else if (scaleType == ImageView.ScaleType.FIT_CENTER) {
      RectF src = new RectF(0, 0, bmWidth, bmHeight);
      RectF dist = new RectF(0, 0, vWidth, vHeight);
      mMatrix.setRectToRect(src, dist, Matrix.ScaleToFit.CENTER);
    } else if (scaleType == ImageView.ScaleType.CENTER_CROP) {
      mMatrix.setScale(scale, scale);
      mMatrix.postTranslate(translateX + 0.5f, translateY + 0.5f);
    }
    return mMatrix;
  }

  private float[] radii;
  private int bitmapHeight;
  private int bitmapWidth;

  private ImageDrawable() {

  }

  @Override
  public void setCornerRadii(float[] radii) {
    this.radii = radii;
    super.setCornerRadii(radii);
  }

  @Override
  protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
      // fix api 21 PaintDrawable crash
      paint.setAntiAlias(false);
    }
    super.onDraw(shape, canvas, paint);
  }

  public
  @Nullable
  float[] getCornerRadii() {
    return this.radii;
  }

  public int getBitmapHeight() {
    return bitmapHeight;
  }

  public int getBitmapWidth() {
    return bitmapWidth;
  }

}
