package com.example.verificationcodejavademo.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.verificationcodejavademo.R;
import com.example.verificationcodejavademo.utils.DisplayUtil;

/**
 * Date:2020/5/19
 * author:wuyan
 */
public class DragImageView extends FrameLayout implements SeekBar.OnSeekBarChangeListener {

    private SeekBar drag_sb;
    private FrameLayout drag_fl_content;
    private ImageView drag_iv_cover;
    private ImageView drag_iv_block;
    private View drag_v_flash;
    private DiyStyleTextView drag_tv_tips;
    private TextView drag_tv_tips2;
    private Bitmap cover;
    private Bitmap block;

    private Long animeTime = 333L;
    private float timeUse = 0.0f;
    private Long timeTemp = 0l;

    private Handler handler = new Handler();

    public DragImageView(@NonNull Context context) {
        super(context);
        init();
    }

    public DragImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DragImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        View.inflate(getContext(), R.layout.drag_view, this);
        drag_sb = findViewById(R.id.drag_sb);
        drag_sb.setOnSeekBarChangeListener(this);
        drag_fl_content = findViewById(R.id.drag_fl_content);
        drag_iv_cover = findViewById(R.id.drag_iv_cover);
        drag_iv_block = findViewById(R.id.drag_iv_block);
        drag_v_flash = findViewById(R.id.drag_v_flash);
        drag_tv_tips = findViewById(R.id.drag_tv_tips);
        drag_tv_tips2 = findViewById(R.id.drag_tv_tips2);
        drag_sb.setMax(getContext().getResources().getDisplayMetrics().widthPixels);
        reset();
    }

    //重置
    public void reset() {
        int position = drag_sb.getProgress();
        if (position != 0) {
            ValueAnimator animator = ValueAnimator.ofFloat(1f, 0.0f);
            animator.setDuration(animeTime).start();
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float f = (float) animation.getAnimatedValue();
                    drag_sb.setProgress((int) (position * f));
                }
            });
        }
        tipsShowAnime(false);
        tips2ShowAnime(true);
        setSbThumb(R.drawable.drag_btn_n);
        drag_sb.setEnabled(true);
        drag_sb.setProgressDrawable(getResources().getDrawable(R.drawable.drag_seek_progress));
        drag_iv_block.setVisibility(VISIBLE);
    }

    /**
     * 设置资源
     *
     * @param cover 拼图
     * @param block 滑块
     */
    public void setUp(Bitmap cover, Bitmap block) {
        this.cover = cover;
        this.block = block;

        int w = cover.getWidth();
        int h = cover.getHeight();

        LayoutParams l = (LayoutParams) drag_iv_cover.getLayoutParams();
        l.width = DisplayUtil.dip2px(getContext(), (float) w);
        l.height = DisplayUtil.dip2px(getContext(), (float) h);

        drag_iv_cover.setLayoutParams(l);
        drag_iv_cover.setImageBitmap(cover);

        LayoutParams layoutParams2 = (LayoutParams) drag_iv_block.getLayoutParams();
        layoutParams2.width = DisplayUtil.dip2px(getContext(), (float) block.getWidth());
        layoutParams2.height = DisplayUtil.dip2px(getContext(), (float) block.getHeight());
        drag_iv_block.setLayoutParams(layoutParams2);
        drag_iv_block.setImageBitmap(block);

        setLocation(1f * cover.getWidth() / cover.getHeight(), cover.getWidth());

    }

    //设置容器宽高
    private void setLocation(float cover_wph, int cover_w) {
        int w = cover_w;
        int h = (int) (w / cover_wph);
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) drag_fl_content.getLayoutParams();
        layoutParams.width = DisplayUtil.dip2px(getContext(), (float) w);
        layoutParams.height = DisplayUtil.dip2px(getContext(), (float) h);
        drag_fl_content.setLayoutParams(layoutParams);
    }

    //验证成功:滑块隐藏,成功提示语,滑块不能滑动,设置setSbThumb,SeekBar的背景
    public void ok() {
        blockHideAnime();

        int penset;
        if (timeUse > 1) {
            penset = (int) (99 - (timeUse - 1) / 0.1f);
        } else {
            penset = (int) (99 - 0 / 0.1f);
        }
        if (penset < 1) penset = 1;
        drag_tv_tips.setText(String.format("拼图成功: 耗时%.1f秒,打败了%d%%的用户!", timeUse, penset));
        tipsShowAnime(true);

        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                tipsShowAnime(false);
                tips2ShowAnime(true);
                drag_sb.setEnabled(true);

                int position = drag_sb.getProgress();
                ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f);
                animator.setDuration(animeTime).start();
                animator.addUpdateListener(animation -> {
                    float f = (float) animation.getAnimatedValue();
                    drag_sb.setProgress((int) (position * f));
                    setSbThumb(R.drawable.drag_btn_n);
                    drag_sb.setProgressDrawable(getResources().getDrawable(R.drawable.drag_seek_progress));
                });

            }
        },1500);

        drag_sb.setEnabled(false);
        setSbThumb(R.drawable.drag_btn_success);
        drag_sb.setProgressDrawable(getResources().getDrawable(R.drawable.drag_seek_progress_success));

    }

    //成功完成拼图滑块消失
    private void blockHideAnime() {
        AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0f);
        alphaAnimation.setDuration(animeTime);
        drag_iv_block.setAnimation(alphaAnimation);
        drag_iv_block.setVisibility(GONE);
    }

    //验证失败
    public void fail() {
        drag_tv_tips.setText("拼图失败: 请重新拖曳滑块到正确的位置!");
        tipsShowAnime(true);
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                tipsShowAnime(false);
                tips2ShowAnime(true);
                drag_sb.setEnabled(true);

                int position = drag_sb.getProgress();
                ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f);
                animator.setDuration(animeTime).start();
                animator.addUpdateListener(animation -> {
                    float f = (float) animation.getAnimatedValue();
                    drag_sb.setProgress((int) (position * f));
                    setSbThumb(R.drawable.drag_btn_n);
                    drag_sb.setProgressDrawable(getResources().getDrawable(R.drawable.drag_seek_progress));
                });

            }
        },1500);
        drag_sb.setEnabled(false);
        setSbThumb(R.drawable.drag_btn_error);
        drag_sb.setProgressDrawable(getResources().getDrawable(R.drawable.drag_seek_progress_fail));
    }

    //弹出提示语是否显示
    private void tipsShowAnime(boolean isShow) {
        TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, isShow ? 1f : 0f, Animation.RELATIVE_TO_SELF, isShow ? 0f : 1f);
        translateAnimation.setDuration(animeTime);
        drag_tv_tips.setAnimation(translateAnimation);
        drag_tv_tips.setVisibility(isShow ? VISIBLE : GONE);
    }

    //seekBar上面的提示语是否显示
    private void tips2ShowAnime(boolean isShow) {
        AlphaAnimation alphaAnimation = new AlphaAnimation(isShow ? 0f : 1f, isShow ? 1f : 0f);
        alphaAnimation.setDuration(animeTime);
        drag_tv_tips2.setAnimation(alphaAnimation);
        drag_tv_tips2.setVisibility(isShow ? VISIBLE : GONE);
    }


    //===================seekbar监听===================

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        int cw = drag_iv_cover.getMeasuredWidth();
        int bw = drag_iv_block.getMeasuredWidth();
        ViewGroup.MarginLayoutParams l = (MarginLayoutParams) drag_iv_block.getLayoutParams();
        l.leftMargin = (cw - bw) * progress / seekBar.getMax();
        drag_iv_block.setLayoutParams(l);
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        setSbThumb(R.drawable.drag_btn_n);
        drag_sb.setProgressDrawable(getResources().getDrawable(R.drawable.drag_seek_progress));
        drag_iv_block.setVisibility(VISIBLE);
        drag_iv_cover.setImageBitmap(cover);
        tips2ShowAnime(false);
        timeTemp = System.currentTimeMillis();
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        timeUse = (System.currentTimeMillis() - timeTemp) / 1000f;//滑动滑块所花的时间,单位s
        if (dragListenner != null) {
            dragListenner.onDrag(DisplayUtil.px2dip(
                    getContext(), (drag_iv_cover.getMeasuredWidth() - drag_iv_block.getMeasuredWidth()) * 1f * seekBar.getProgress() / seekBar.getMax()
            ));
        }


    }

    //设置seekBar的Thumb
    private void setSbThumb(int id) {
        Drawable drawable = getResources().getDrawable(id);
        drawable.setBounds(drag_sb.getThumb().getBounds());
        drag_sb.setThumb(drawable);
        drag_sb.setThumbOffset(0);
    }

    //设置seekBar是否可以滑动
    public void setSBUnMove(boolean isMove) {
        drag_sb.setEnabled(isMove);
    }

    //设置滑动监听
    private DragListenner dragListenner;

    interface DragListenner {
        void onDrag(double position);
    }

    public void setDragListenner(DragListenner dragListenner) {
        this.dragListenner = dragListenner;
    }
}