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

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

import com.taobao.weex.WXEnvironment;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.adapter.IWXImgLoaderAdapter;
import com.taobao.weex.adapter.URIAdapter;
import com.taobao.weex.annotation.Component;
import com.taobao.weex.annotation.JSMethod;
import com.taobao.weex.bridge.JSCallback;
import com.taobao.weex.common.Constants;
import com.taobao.weex.common.WXImageSharpen;
import com.taobao.weex.common.WXImageStrategy;
import com.taobao.weex.common.WXRuntimeException;
import com.taobao.weex.dom.ImmutableDomObject;
import com.taobao.weex.dom.WXDomObject;
import com.taobao.weex.ui.ComponentCreator;
import com.taobao.weex.ui.view.WXImageView;
import com.taobao.weex.ui.view.border.BorderDrawable;
import com.taobao.weex.utils.ImageDrawable;
import com.taobao.weex.utils.ImgURIUtil;
import com.taobao.weex.utils.SingleFunctionParser;
import com.taobao.weex.utils.WXViewToImageUtil;
import com.taobao.weex.utils.WXDomUtils;
import com.taobao.weex.utils.WXLogUtils;
import com.taobao.weex.utils.WXUtils;
import com.taobao.weex.utils.WXViewUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Image component
 */
@Component(lazyload = false)
public class WXImage extends WXComponent<ImageView> {

  public static final String SUCCEED = "success";
  public static final String ERRORDESC = "errorDesc";
  private static final int WRITE_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 0x2;

  private String mSrc;
  private int mBlurRadius;

  private static SingleFunctionParser.FlatMapper<Integer> BLUR_RADIUS_MAPPER = new SingleFunctionParser.FlatMapper<Integer>() {
    @Override
    public Integer map(String raw) {
      return WXUtils.getInteger(raw,0);
    }
  };

  public static class Ceator implements ComponentCreator {
    public WXComponent createInstance(WXSDKInstance instance, WXDomObject node, WXVContainer parent) throws IllegalAccessException, InvocationTargetException, InstantiationException {
        return new WXImage(instance,node,parent);
    }
  }


  @Deprecated
  public WXImage(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, String instanceId, boolean isLazy) {
      this(instance,dom,parent);
  }

  public WXImage(WXSDKInstance instance, WXDomObject node,
                  WXVContainer parent) {
      super(instance, node, parent);
  }

  @Override
  protected ImageView initComponentHostView(@NonNull Context context) {
    WXImageView view = new WXImageView(context);
    view.setScaleType(ScaleType.FIT_XY);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
      view.setCropToPadding(true);
    }
    view.holdComponent(this);
    return view;
  }

    @Override
    protected boolean setProperty(String key, Object param) {
      switch (key) {
        case Constants.Name.RESIZE_MODE:
          String resize_mode = WXUtils.getString(param, null);
          if (resize_mode != null)
            setResizeMode(resize_mode);
          return true;
        case Constants.Name.RESIZE:
          String resize = WXUtils.getString(param, null);
          if (resize != null)
            setResize(resize);
          return true;
        case Constants.Name.SRC:
          String src = WXUtils.getString(param, null);
          if (src != null)
            setSrc(src);
          return true;
        case Constants.Name.IMAGE_QUALITY:
          return true;
        case Constants.Name.FILTER:
          int blurRadius = 0;
          if(param != null && param instanceof String) {
            blurRadius = parseBlurRadius((String)param);
          }
          if(!TextUtils.isEmpty(this.mSrc)) {
            setBlurRadius(this.mSrc,blurRadius);
          }
          return true;
      }
    return super.setProperty(key, param);
  }

  @Override
  public void refreshData(WXComponent component) {
    super.refreshData(component);
    if (component instanceof WXImage) {
      setSrc(component.getDomObject().getAttrs().getImageSrc());
    }
  }

  @WXComponentProp(name = Constants.Name.RESIZE_MODE)
  public void setResizeMode(String resizeMode) {
    (getHostView()).setScaleType(getResizeMode(resizeMode));
  }

  private ScaleType getResizeMode(String resizeMode) {
    ScaleType scaleType = ScaleType.FIT_XY;
    if (TextUtils.isEmpty(resizeMode)) {
      return scaleType;
    }

    switch (resizeMode) {
      case "cover":
        scaleType = ScaleType.CENTER_CROP;
        break;
      case "contain":
        scaleType = ScaleType.FIT_CENTER;
        break;
      case "stretch":
        scaleType = ScaleType.FIT_XY;
        break;
    }
    return scaleType;
  }

  @WXComponentProp(name = Constants.Name.RESIZE)
  public void setResize(String resize) {
    (getHostView()).setScaleType(getResizeMode(resize));
  }

  /**
   * Process local scheme, load drawable.
   * @param rewrited
   */
  private void setLocalSrc(Uri rewrited) {
    ImageView imageView;
    Drawable localDrawable = ImgURIUtil.getDrawableFromLoaclSrc(getContext(), rewrited);
    if (localDrawable != null && (imageView = getHostView()) != null) {
      imageView.setImageDrawable(localDrawable);
    }
  }

  @WXComponentProp(name = Constants.Name.SRC)
  public void setSrc(String src) {
    if (src == null) {
      return;
    }

    ImageView image = getHostView();
    if("".equals(src) && image != null){
      image.setImageDrawable(null);
      return;
    }

    if(image != null){
      if(image.getDrawable() != null){
         image.setImageDrawable(null);
      }
    }


    this.mSrc = src;
    WXSDKInstance instance = getInstance();
    Uri rewrited = instance.rewriteUri(Uri.parse(src), URIAdapter.IMAGE);

    if (Constants.Scheme.LOCAL.equals(rewrited.getScheme())) {
      setLocalSrc(rewrited);
    } else {
      int blur = 0;
      if(getDomObject() != null) {
        String blurStr = getDomObject().getStyles().getBlur();
        blur = parseBlurRadius(blurStr);
      }
      setRemoteSrc(rewrited, blur);
    }
  }

  private void setBlurRadius(@NonNull String src, int blurRadius) {
    if(getInstance() != null && blurRadius != mBlurRadius) {
      Uri parsedUri = getInstance().rewriteUri(Uri.parse(src), URIAdapter.IMAGE);
      if(!Constants.Scheme.LOCAL.equals(parsedUri.getScheme())) {
        setRemoteSrc(parsedUri,blurRadius);
      }
    }
  }

  private int parseBlurRadius(@Nullable String rawRadius) {
    if(rawRadius == null) {
      return 0;
    }
    SingleFunctionParser<Integer> parser = new SingleFunctionParser<Integer>(rawRadius,BLUR_RADIUS_MAPPER);
    List<Integer> list = null;
    try {
       list = parser.parse("blur");
    }catch (Exception e) {
      return 0;
    }
    if(list == null || list.isEmpty()) {
      return 0;
    }
    return list.get(0);
  }

  @Override
  public void recycled() {
    super.recycled();

    if (getInstance().getImgLoaderAdapter() != null) {
      getInstance().getImgLoaderAdapter().setImage(null, mHost,
              null, null);
    } else {
      if (WXEnvironment.isApkDebugable()) {
        throw new WXRuntimeException("getImgLoaderAdapter() == null");
      }
      WXLogUtils.e("Error getImgLoaderAdapter() == null");
    }
  }

  private void setRemoteSrc(Uri rewrited,int blurRadius) {

      WXImageStrategy imageStrategy = new WXImageStrategy();
      imageStrategy.isClipping = true;

      WXImageSharpen imageSharpen = getDomObject().getAttrs().getImageSharpen();
      imageStrategy.isSharpen = imageSharpen == WXImageSharpen.SHARPEN;

      imageStrategy.blurRadius = Math.max(0, blurRadius);
      this.mBlurRadius = blurRadius;

      imageStrategy.setImageListener(new WXImageStrategy.ImageListener() {
        @Override
        public void onImageFinish(String url, ImageView imageView, boolean result, Map extra) {
          if (getDomObject() != null && getDomObject().getEvents().contains(Constants.Event.ONLOAD)) {
            Map<String, Object> params = new HashMap<String, Object>();
            Map<String, Object> size = new HashMap<>(2);
            if (imageView != null && imageView instanceof Measurable) {
              size.put("naturalWidth", ((Measurable) imageView).getNaturalWidth());
              size.put("naturalHeight", ((Measurable) imageView).getNaturalHeight());
            } else {
              size.put("naturalWidth", 0);
              size.put("naturalHeight", 0);
            }

            if (getDomObject() != null && containsEvent(Constants.Event.ONLOAD)) {
              params.put("success", result);
              params.put("size", size);
              fireEvent(Constants.Event.ONLOAD, params);
            }
          }
        }
      });

        String placeholder=null;
        if(getDomObject().getAttrs().containsKey(Constants.Name.PLACEHOLDER)){
            placeholder= (String) getDomObject().getAttrs().get(Constants.Name.PLACEHOLDER);
        }else if(getDomObject().getAttrs().containsKey(Constants.Name.PLACE_HOLDER)){
            placeholder=(String)getDomObject().getAttrs().get(Constants.Name.PLACE_HOLDER);
        }
        if(placeholder!=null){
            imageStrategy.placeHolder = getInstance().rewriteUri(Uri.parse(placeholder),URIAdapter.IMAGE).toString();
        }

      IWXImgLoaderAdapter imgLoaderAdapter = getInstance().getImgLoaderAdapter();
      if (imgLoaderAdapter != null) {
        imgLoaderAdapter.setImage(rewrited.toString(), getHostView(),
            getDomObject().getAttrs().getImageQuality(), imageStrategy);
      }
  }

  @Override
  public void updateProperties(Map<String, Object> props) {
    super.updateProperties(props);
    WXImageView imageView;
    ImmutableDomObject imageDom;
    if ((imageDom = getDomObject()) != null &&
        getHostView() instanceof WXImageView) {
      imageView = (WXImageView) getHostView();
      BorderDrawable borderDrawable = WXViewUtils.getBorderDrawable(getHostView());
      float[] borderRadius;
      if (borderDrawable != null) {
        RectF borderBox = new RectF(0, 0, WXDomUtils.getContentWidth(imageDom), WXDomUtils.getContentHeight(imageDom));
        borderRadius = borderDrawable.getBorderRadius(borderBox);
      } else {
        borderRadius = new float[]{0, 0, 0, 0, 0, 0, 0, 0};
      }
      imageView.setBorderRadius(borderRadius);

      if (imageView.getDrawable() instanceof ImageDrawable) {
        ImageDrawable imageDrawable = (ImageDrawable) imageView.getDrawable();
        float[] previousRadius = imageDrawable.getCornerRadii();
        if (!Arrays.equals(previousRadius, borderRadius)) {
          imageDrawable.setCornerRadii(borderRadius);
        }
      }
      readyToRender();
    }
  }

  /**
   * Need permission {android.permission.WRITE_EXTERNAL_STORAGE}
   */
  @JSMethod(uiThread = false)
  public void save(final JSCallback saveStatuCallback) {

    if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
      if (getContext() instanceof Activity) {
        ActivityCompat.requestPermissions((Activity) getContext(),
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
      }
    }

    if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
      if (saveStatuCallback != null) {
        Map<String, Object> result = new HashMap<>();
        result.put(SUCCEED, false);
        result.put(ERRORDESC,"Permission denied: android.permission.WRITE_EXTERNAL_STORAGE");
        saveStatuCallback.invoke(result);
      }
      return;
    }

    if (mHost == null) {
      if (saveStatuCallback != null) {
        Map<String, Object> result = new HashMap<>();
        result.put(SUCCEED, false);
        result.put(ERRORDESC,"Image component not initialized");
        saveStatuCallback.invoke(result);
      }
      return;
    }

    if (mSrc == null || mSrc.equals("")) {
      if (saveStatuCallback != null) {
        Map<String, Object> result = new HashMap<>();
        result.put(SUCCEED, false);
        result.put(ERRORDESC,"Image does not have the correct src");
        saveStatuCallback.invoke(result);
      }
      return;
    }

    WXViewToImageUtil.generateImage(mHost, 0, 0xfff8f8f8, new WXViewToImageUtil.OnImageSavedCallback() {
      @Override
      public void onSaveSucceed(String path) {
        if (saveStatuCallback != null) {
          Map<String, Object> result = new HashMap<>();
          result.put(SUCCEED, true);
          saveStatuCallback.invoke(result);
        }
      }

      @Override
      public void onSaveFailed(String errorDesc) {
        if (saveStatuCallback != null) {
          Map<String, Object> result = new HashMap<>();
          result.put(SUCCEED, false);
          result.put(ERRORDESC,errorDesc);
          saveStatuCallback.invoke(result);
        }
      }
    });
  }

  public interface Measurable {
    int getNaturalWidth();
    int getNaturalHeight();
  }
}
