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

import android.graphics.Color;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
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.ui.action.BasicComponentData;
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.ui.component.list.BasicListComponent;
import com.taobao.weex.ui.component.list.template.WXRecyclerTemplateList;
import com.taobao.weex.ui.view.listview.WXRecyclerView;
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 = "";
  WXComponent mBindingComponent;

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

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

    mBindingRef = (String) (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) (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) {
    if(ViewCompat.isInLayout(view)){
      if(mBindingComponent == null && mBindingRef != null){
        mBindingComponent = findComponent(mBindingRef);
      }
      if(mBindingComponent instanceof BasicListComponent
              && view instanceof RecyclerView){
        BasicListComponent listComponent = (BasicListComponent) mBindingComponent;
        mOffsetY = Math.abs(listComponent.calcContentOffset((RecyclerView) view));
      }else if(mBindingComponent instanceof WXRecyclerTemplateList
              && view instanceof RecyclerView){
        WXRecyclerTemplateList listComponent = (WXRecyclerTemplateList) mBindingComponent;
        mOffsetY = Math.abs(listComponent.calcContentOffset((RecyclerView) view));
      }
    }else{
       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;
    }
  }
}
