package com.autotech.we1l.helpers;

import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.CardView;
import android.view.View;

public class AnimatorUtils {

    private static final int ANIMATION_DURATION = 200;
    public static final float SCALE_TO = 1.2f, SCALE_FROM = 1f;
//    private static final Context CONTEXT = MyApp.getInstance().getApplicationContext();

    public static void show(View view) {
        show(view, null);
    }

    private static void show(View view, @Nullable Runnable runnable) {

        view.setAlpha(0);
        view.setVisibility(View.VISIBLE);
        view.animate().alpha(1).setDuration(ANIMATION_DURATION).withEndAction(runnable).start();
    }

    public static void vanish(View view) {
        view.animate().alpha(0).setDuration(ANIMATION_DURATION).withEndAction(() -> view.setVisibility(View.GONE)).start();
    }

    public static void vanish(View view, Runnable runnable) {

        view.animate().alpha(0).setDuration(ANIMATION_DURATION).withEndAction(() -> {
            view.setVisibility(View.GONE);
            if (runnable != null) runnable.run();
        }).start();
    }

    public static void hide(View view) {
        hide(view, null);
    }

    public static void hide(View view, Runnable runnable) {
        if (view == null)
            return;
        view.animate().alpha(0).setDuration(ANIMATION_DURATION).withEndAction(() -> {
            view.setVisibility(View.INVISIBLE);
            if (runnable != null) runnable.run();
        }).start();
    }


    public static void hideThenShow(View view, Runnable runnable) {
        if (view == null)
            return;

        view.setAlpha(0);
        view.setVisibility(View.VISIBLE);
        view.animate().alpha(1).setDuration(ANIMATION_DURATION).withStartAction(runnable).start();
    }

    public static void moveLeft(View view, Runnable runnable) {
        move(view, runnable, -20);
    }

    public static void moveRight(View view, Runnable runnable) {
        move(view, runnable, 20);
    }

    private static void move(View view, Runnable runnable, float value) {
        if (view == null)
            return;

        view.animate().translationXBy(value).setDuration(ANIMATION_DURATION / 2).start();
        view.animate().alpha(0).setDuration(ANIMATION_DURATION / 2).withEndAction(() -> {
            view.setTranslationX(0);
            hideThenShow(view, runnable);
        }).start();
    }

    public static void rotateBy(View view, float rotateFrom, float rotateTo) {
        if (view == null)
            return;

        view.setRotation(rotateFrom);
        view.animate().rotationBy(Math.abs(rotateTo - rotateFrom)).setDuration(ANIMATION_DURATION).start();
    }


//    public static void selectItem(View view, Context context) {
//        termSelection(view, 1f, context.getResources().getColor(R.color.grey_3), context.getResources().getColor(R.color.purple_1));
//    }

//    public static void unSelectItem(View view, Context context) {
//        termSelection(view, 1, context.getResources().getColor(R.color.purple_1), context.getResources().getColor(R.color.grey_3));
//    }

    private static void termSelection(View view, float value, Object... objects) {
        AppCompatTextView textView = (AppCompatTextView) view;
        ObjectAnimator.ofObject(textView,
                "textColor",
                new ArgbEvaluator(),
                objects)
                .setDuration(ANIMATION_DURATION)
                .start();

        view.animate().scaleY(value).setDuration(ANIMATION_DURATION).start();
        view.animate().scaleX(value).setDuration(ANIMATION_DURATION).start();
    }

    public static void changeBGColor(View view, int colorFrom, int colorTo) {
        ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
        colorAnimation.addUpdateListener(animation -> view.setBackgroundColor((int) animation.getAnimatedValue()));
        colorAnimation.setDuration(ANIMATION_DURATION * 2);
        colorAnimation.start();
    }

    public static void changeColor(View view, int color1, int color2) {
        AppCompatImageView imageView = (AppCompatImageView) view;
        ValueAnimator animation = new ValueAnimator();
        animation.setIntValues(color1, color2);
        animation.setEvaluator(new ArgbEvaluator());
        animation.addUpdateListener(valueAnimator -> imageView.setColorFilter((Integer) valueAnimator.getAnimatedValue()));

        animation.setDuration(ANIMATION_DURATION);
        animation.start();
    }

    public static void disable(View view, boolean shouldDisable) {
        status(view, 0.5f, shouldDisable, false);
    }

    public static void enable(View view, boolean shouldEnable) {
        status(view, 1, shouldEnable, true);
    }

    private static void status(View view, float value, boolean shouldEnable, boolean enable) {
        view.animate().alpha(value).setDuration(ANIMATION_DURATION).withStartAction(() -> {
            if (shouldEnable) {
                view.setEnabled(enable);
            }
        }).start();
    }

    public static void scaleBy(View view, float scale) {
        view.animate().scaleX(scale).setDuration(ANIMATION_DURATION);
        view.animate().scaleY(scale).setDuration(ANIMATION_DURATION);
    }

    public static void scaleBy(View view, float scaleFrom, float scaleTo) {
        view.setScaleX(scaleFrom);
        view.setScaleY(scaleFrom);
        view.animate().scaleX(scaleTo).setDuration(ANIMATION_DURATION);
        view.animate().scaleY(scaleTo).setDuration(ANIMATION_DURATION);
    }

    public static void scaleBy(View view, float scaleFrom, float scaleTo, Runnable onEnd) {
        view.setScaleX(scaleFrom);
        view.setScaleY(scaleFrom);
        view.animate().scaleX(scaleTo).setDuration(ANIMATION_DURATION);
        view.animate().scaleY(scaleTo).setDuration(ANIMATION_DURATION).withEndAction(onEnd);
    }

    public static void elevateCardView(CardView cardView, int from, int to) {
        ObjectAnimator animator = ObjectAnimator
                .ofFloat(cardView, "cardElevation", from, to)
                .setDuration(ANIMATION_DURATION);

        animator.start();
    }

}
