/**
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.alibaba.weex.extend.component;

import android.graphics.Color;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.taobao.weex.WXEnvironment;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.common.Constants;
import com.taobao.weex.common.ICheckBindingScroller;
import com.taobao.weex.common.OnWXScrollListener;
import com.taobao.weex.dom.WXDomObject;
import com.taobao.weex.ui.animation.WXAnimationBean;
import com.taobao.weex.ui.component.Scrollable;
import com.taobao.weex.ui.component.WXComponent;
import com.taobao.weex.ui.component.WXDiv;
import com.taobao.weex.ui.component.WXVContainer;
import com.taobao.weex.utils.WXLogUtils;
import com.taobao.weex.utils.WXResourceUtils;

import java.util.ArrayList;


/**
 * Created by zhengshihan on 2017/5/3.
 */

public class WXParallax extends WXDiv implements OnWXScrollListener, ICheckBindingScroller {

  public final static String WX_TRANSFORM = "transform";
  public final static String WX_OPACITY = "opacity";
  public static final String PARALLAX = "parallax";
  public static final String BINDING_SCROLLER = "bindingScroller";


  ArrayList<TransformCreator> mTransformPropArrayList = new ArrayList<>();
  BackgroundColorCreator mBackgroundColor;
  String mBindingRef = "";

  private int mBackGroundColor = 0;
  private float mOffsetY = 0;

  public WXParallax(WXSDKInstance instance, WXDomObject dom, WXVContainer parent) {
    super(instance, dom, parent);
    initTransform(dom.getAttrs().get(WX_TRANSFORM));
    initOpacity(dom.getAttrs().get(Constants.Name.OPACITY));
    initBackgroundColor(dom.getAttrs().get(Constants.Name.BACKGROUND_COLOR));

    mBindingRef = (String) (dom.getAttrs().get(BINDING_SCROLLER));
    instance.registerOnWXScrollListener(this);
  }


  private void initBackgroundColor(Object obj) {
    if (obj == null)
      return;

    if (obj instanceof JSONObject) {
      mBackgroundColor = new BackgroundColorCreator();
      JSONObject object = (JSONObject) obj;

      JSONArray in = object.getJSONArray("in");
      mBackgroundColor.input = new int[in.size()];
      for (int i = 0; i < in.size(); i++) {
        mBackgroundColor.input[i] = in.getInteger(i);
      }

      JSONArray out = object.getJSONArray("out");
      mBackgroundColor.output = new int[out.size()];
      for (int i = 0; i < out.size(); i++) {
        String colorStr = out.getString(i);
        mBackgroundColor.output[i] = WXResourceUtils.getColor(colorStr);
      }
    }
  }

  private void initOpacity(Object obj) {
    if (obj == null)
      return;

    if (obj instanceof JSONObject) {
      mTransformPropArrayList.add(new TransformCreator(WX_OPACITY, (JSONObject) obj));
    }

  }

  private void initTransform(Object propStr) {

    if (propStr == null) {
      WXLogUtils.w("WXParallax initAnimation propStr ==null");
      return;
    }
    JSONArray jsonObject;
    if (propStr instanceof JSONArray) {
      jsonObject = (JSONArray) propStr;
      for (int i = 0; i < jsonObject.size(); i++) {
        JSONObject object = jsonObject.getJSONObject(i);
        mTransformPropArrayList.add(i,
            new TransformCreator(object.getString("type"), object));
      }
    }
  }

  @Override
  public boolean isNeedScroller(String ref, Object option) {

    mBindingRef = (String) (getDomObject().getAttrs().get(BINDING_SCROLLER));
    if (TextUtils.isEmpty(mBindingRef)) {
      WXComponent root = getInstance().getRootComponent();
      if (root != null && root instanceof WXVContainer) {
        Scrollable scrollable = root.getFirstScroller();
        if (scrollable != null) {
          mBindingRef = scrollable.getRef();
        }
      }
    }
    if (!TextUtils.isEmpty(mBindingRef)
        && !TextUtils.isEmpty(ref)
        && ref.equals(mBindingRef)) {
      return true;
    }
    return false;
  }

  @Override
  public void onScrolled(View view, int dx, int dy) {

    mOffsetY = mOffsetY + dy;

    AnimationSet animationSet = new AnimationSet(true);
    boolean hasAnimation = false;
    for (int i = 0; i < mTransformPropArrayList.size(); i++) {
      TransformCreator creator = mTransformPropArrayList.get(i);
      Animation animation = creator.getAnimation(dx, dy);
      if (animation != null) {
        animationSet.addAnimation(animation);
        hasAnimation = true;
      }
    }

    if (hasAnimation) {
      animationSet.setFillAfter(true);
      if (getHostView() != null) {
        getHostView().startAnimation(animationSet);
      }
    }

    if (mBackgroundColor != null) {
      int color = mBackgroundColor.getColor(dx, dy);
      if (mBackGroundColor != color) {
        getHostView().setBackgroundColor(color);
        mBackGroundColor = color;
      }
    }
  }

  @Override
  public void onScrollStateChanged(View view, int x, int y, int newState) {

  }


  private class BackgroundColorCreator {

    int[] input;
    int[] output;

    int getColor(int XDelta, int YDelta) {
      if (WXEnvironment.isApkDebugable()) {
        WXLogUtils.d("WXParallax:getColor: XDelta" + XDelta + " YDelta:" + YDelta + " mOffsetY" + mOffsetY);
      }
      int r1, g1, b1;

      if (mOffsetY > input[1]) {
        return output[1];
      }

      if (mOffsetY < input[0]) {
        return output[0];
      }

      r1 = Color.red(output[0]) + (int) (mOffsetY - input[0]) * (Color.red(output[1]) - Color.red(output[0])) / (input[1] - input[0]);
      g1 = Color.green(output[0]) + (int) (mOffsetY - input[0]) * (Color.green(output[1]) - Color.green(output[0])) / (input[1] - input[0]);
      b1 = Color.blue(output[0]) + (int) (mOffsetY - input[0]) * (Color.blue(output[1]) - Color.blue(output[0])) / (input[1] - input[0]);

      if (WXEnvironment.isApkDebugable()) {
        WXLogUtils.d("WXParallax:getColor: r1" + r1 + " g1:" + g1 + " b1:" + b1);
      }
      return Color.rgb(r1, g1, b1);
    }

  }

  private class TransformCreator {

    String transformType;
    float[] input, output;
    float fromTranslateX, fromTranslateY;
    float fromScaleX, fromScaleY;
    float fromRotate, fromOpacity;

    TransformCreator(String type, JSONObject object) {
      transformType = type;
      JSONArray in = object.getJSONArray("in");
      input = parseParamArray(in);
      JSONArray out = object.getJSONArray("out");
      output = parseParamArray(out);

      switch (transformType) {
        case WXAnimationBean.Style.WX_TRANSLATE:
          fromTranslateX = output[0];
          fromTranslateY = output[1];
          break;
        case WXAnimationBean.Style.WX_SCALE:
          fromScaleX = output[0];
          fromScaleY = output[1];
          break;
        case WXAnimationBean.Style.WX_ROTATE:
          fromRotate = output[0];
          break;
        case WX_OPACITY:
          fromOpacity = output[0];
          break;
      }
    }

    float[] parseParamArray(JSONArray in) {

      int size = in.size();
      float[] param = new float[size];
      for (int j = 0; j < size; j++) {
        param[j] = in.getFloatValue(j);
      }
      return param;
    }


    @Nullable
    Animation getAnimation(float XDelta, float YDelta) {

      float offset = mOffsetY;
      if (offset > input[1]) {
        offset = input[1];
      }
      if (offset < input[0]) {
        offset = input[0];
      }
      float toTranslateX, toTranslateY, toOpacity, toScaleX, toScaleY, toRotate;
      Animation animation = null;

      if (WXEnvironment.isApkDebugable()) {
        WXLogUtils.d("WXParallax", "type:" + transformType + " XDelta:" + XDelta + " YDelta:" + YDelta);
      }
      switch (transformType) {

        case WXAnimationBean.Style.WX_TRANSLATE:
          toTranslateX = output[0] + (output[2] - output[0]) * (offset - input[0]) / (input[1] - input[0]);
          toTranslateY = output[1] + (output[3] - output[1]) * (offset - input[0]) / (input[1] - input[0]);

          if (fromTranslateX == toTranslateX && fromTranslateY == toTranslateY) {
            return null;
          }
          animation = new TranslateAnimation(fromTranslateX, toTranslateX, fromTranslateY, toTranslateY);

          fromTranslateX = toTranslateX;
          fromTranslateY = toTranslateY;

          if (WXEnvironment.isApkDebugable()) {
            WXLogUtils.d("WXParallax", "XDelta:" + XDelta + " YDelta:" + YDelta);
            WXLogUtils.d("WXParallax", " fromTranslateX:" + fromTranslateX + " toTranslateX:" + toTranslateX + " fromTranslateY:" + fromTranslateY + " toTranslateY:" + toTranslateY);
          }

          break;
        case WXAnimationBean.Style.WX_SCALE:
          toScaleX = output[0] + (output[2] - output[0]) * (offset - input[0]) / (input[1] - input[0]);
          toScaleY = output[1] + (output[3] - output[1]) * (offset - input[0]) / (input[1] - input[0]);

          if (fromScaleX == toScaleX && fromScaleY == toScaleY) {
            return null;
          }
          animation = new ScaleAnimation(fromScaleX, toScaleX, fromScaleY, toScaleY);

          if (WXEnvironment.isApkDebugable()) {
            WXLogUtils.d("WXParallax", " fromScaleX:" + fromScaleX + " toScaleX:" + toScaleX + " fromScaleY:" + fromScaleY + " toScaleY:" + toScaleY);
          }

          fromScaleX = toScaleX;
          fromScaleY = toScaleY;
          break;

        case WXAnimationBean.Style.WX_ROTATE:
          toRotate = output[0] + (output[1] - output[0]) * (offset - input[0]) / (input[1] - input[0]);
          if (fromRotate == toRotate) {
            return null;
          }
          animation = new RotateAnimation(fromRotate, toRotate, output[2], output[3]);
          fromRotate = toRotate;
          break;

        case WX_OPACITY:
          toOpacity = output[0] + (output[1] - output[0]) * (offset - input[0]) / (input[1] - input[0]);
          if (fromOpacity == toOpacity) {
            return null;
          }
          setOpacity(toOpacity);
//        animation = new AlphaAnimation(fromOpacity, toOpacity);

          if (WXEnvironment.isApkDebugable()) {
            WXLogUtils.d("WXParallax", "opacity fromOpacity:" + fromOpacity + " toOpacity:" + toOpacity);
          }

          fromOpacity = toOpacity;
          break;
      }

      return animation;
    }
  }
}
