package com.xunao.effectdemo.activity;

import android.animation.Animator;
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.app.Activity;


import android.content.ClipData;
import android.graphics.PointF;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import androidx.annotation.NonNull;

import com.xunao.effectdemo.R;
import com.xunao.effectdemo.bean.ListBean;
import com.xunao.effectdemo.dragview.DragViewUtil;

import java.util.ArrayList;
import java.util.List;


/**
 * author : 程中强
 * e-mail : 740479946@qq.com
 * date : 2022/8/318:12
 * desc :
 * version: 1.0
 */
public class Test2Activity extends Activity {

	private final static String TAG = "DragViewActivity";
	/** 三个容器 */
	private LinearLayout view1_container;
	private LinearLayout view2_container;
	private LinearLayout view3_container;
	private LinearLayout view4_container;
	/** 三要个拖动view */
	private LinearLayout view1;
	private LinearLayout view2;
	private LinearLayout view3;
	private LinearLayout view4;

	private List<View> list = new ArrayList<>();
	private List<LinearLayout> mlist = new ArrayList<>();
	private LinearLayout view_1;
	private LinearLayout view_2;
	private LinearLayout view_3;
	private LinearLayout view_4;
	private View v1;
	//被拖view
	View draggingView;
	//当前容器
	ViewGroup thisContainer ;
	//被拖拽view覆盖的view
	View coveredView ;
	ViewGroup draggingViewContainer;
	Animation aset_4;
	Animation animation4;
	Animation animDown,animUp;
	View viewCover;
	ImageView imv;
	Button btn;
	private LinearLayout ll_move,ll_2,ll_1,ll_3,ll_4;
	private RelativeLayout rl_main;
	private ListBean bean;
	private List<ListBean> beanList = new ArrayList<>();//用于记录数据
	private List<LinearLayout> viewList = new ArrayList<>();//显示合并的view的集合
	boolean isResult = false;

	private Handler handler = new Handler(new Handler.Callback() {
		@Override
		public boolean handleMessage(@NonNull Message message) {
			switch (message.what){
				case 1:
					Log.e("MyTag","获取消息"+isResult);
					if (isResult){
						isResult = false;
						setResult();
					}
					break;
			}
			return false;
		}
	});

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_test2);
		init();
		initAnim();
	}

	void init(){

		ll_move = findViewById(R.id.ll_move);
		rl_main = findViewById(R.id.rl_main);

		ll_2 = findViewById(R.id.ll_2);
		ll_1 = findViewById(R.id.ll_1);
		ll_3= findViewById(R.id.ll_3);
		ll_4 = findViewById(R.id.ll_4);
		viewList.add(ll_1);
		viewList.add(ll_2);
		viewList.add(ll_3);
		viewList.add(ll_4);
		//三个容器
		view1_container = findViewById(R.id.view1_container);
		view2_container = findViewById(R.id.view2_container);
		view3_container = findViewById(R.id.view3_container);
		view4_container = findViewById(R.id.view4_container);
		mlist.add(view1_container);
		mlist.add(view2_container);
		mlist.add(view3_container);
		mlist.add(view4_container);

		//三个可拖拽view
		view1 = findViewById(R.id.view1);
		view2 = findViewById(R.id.view2);
		view3 = findViewById(R.id.view3);
		view4 = findViewById(R.id.view4);
		view_1 = findViewById(R.id.view_1);
		view_2 = findViewById(R.id.view_2);
		view_3 = findViewById(R.id.view_3);
		view_4 = findViewById(R.id.view_4);
		list.add(view_1);
		list.add(view_2);
		list.add(view_3);
		list.add(view_4);

//		v1 = findViewById(R.id.v_1);

		//拖拽view1触摸事件
		setTouchText(view1,"1");
		setTouchText(view2,"2");
		setTouchText(view3,"3");
		setTouchText(view4,"4");
		/**
		 * 整理为一个通用的拖拽回调逻辑.所有容器view设置这个回调对象.
		 *
		 * 拖拽回调解释: 当一个view被拖拽的时候,系统会回调任何可见的view(包括被拖拽view自己)的OnDragListener,
		 * 当然如果view没设置OnDragListener不会被系统回调.
		 *
		 */

		//container设置拖拽监听, 感知其他view的拖动
		view1_container.setOnDragListener(onDragListener1);
		view2_container.setOnDragListener(onDragListener1);
		view3_container.setOnDragListener(onDragListener1);
		view4_container.setOnDragListener(onDragListener1);
		view_1.setOnDragListener(onDragListener1);
		view_2.setOnDragListener(onDragListener1);
		view_3.setOnDragListener(onDragListener1);
		view_4.setOnDragListener(onDragListener1);
//		btn.setOnDragListener(onDragListener1);
		beanList.clear();
		for (int i=0;i<4;i++){
			bean = new ListBean();
			bean.setView(mlist.get(i));
			bean.setAnswer((i+1)%4);
			bean.setNum(i);
			bean.setStatus(false);
			beanList.add(bean);
		}

		imv = findViewById(R.id.imv_reset2);
		btn = findViewById(R.id.btn);
		imv.setOnClickListener(v->{
			setResult();
		});
		btn.setOnClickListener(v->{
//			for (ListBean bean:beanList){
//				if (bean.isStatus()){
////					openView(bean.getView(),(ViewGroup) bean.getView().getParent());
//				}else{
//					closeView(bean.getView(),(ViewGroup) bean.getView().getParent());
//				}
//
//			}
		});

		DragViewUtil.registerDragAction(btn);
	}

	/**
	 * 计算最后答案
	 */
	void setResult(){
		for (ListBean b: beanList){
			if (b.getAnswer() != b.getNum()){
				for (ListBean b2: beanList){
					if (b2.getNum() == b.getAnswer()){
						isResult = true;
						changeToView(b.getView(),b2.getView(),500);
						return;
					}
				}
			}
		}
	}

	void initAnim(){
		animDown = new TranslateAnimation(0, 0, 0, 20);
		animDown.setDuration(400);
		animDown.setRepeatCount(0);//动画的反复次数
		animDown.setFillAfter(false);//设置为true，动画转化结束后被应用

//		animUp= new TranslateAnimation(0, 0, 0, -20);
//		animUp.setDuration(400);
//		animUp.setRepeatCount(0);//动画的反复次数
//		animUp.setFillAfter(true);//设置为true，动画转化结束后被应用

		aset_4 = new TranslateAnimation(0, 0, -20, 20);
		aset_4.setDuration(100);//每次时间
		aset_4.setRepeatCount(3);//重复次数
		/**倒序重复REVERSE 正序重复RESTART**/
		aset_4.setRepeatMode(Animation.REVERSE);

		animation4 = AnimationUtils.loadAnimation(Test2Activity.this, R.anim.anim_small);


	}
	private float downX;
	private float downY;
	void setTouchText(View v,String tag){
		v.setOnClickListener(v1->{});
		v.setOnTouchListener(new View.OnTouchListener() {
			@Override
			public boolean onTouch(View view, MotionEvent event) {
				switch (event.getAction()) {
					case MotionEvent.ACTION_DOWN:
						downX = event.getX();
						downY = event.getY();
//						ClipData clipData = new ClipData(ClipData.newPlainText("text", tag));
//						//定义一个拖拽阴影
//						View.DragShadowBuilder myShadow = new View.DragShadowBuilder(view);
//						//开始拖拽. 第三个参数在拖拽过程用来传递数据,这里我传view即被拖动的view自己,
//						//后面可在DragEvent中获得这个参数view
//						view.startDrag(clipData, myShadow, view, 0);
//						view.setVisibility(View.INVISIBLE);
						break;
					case MotionEvent.ACTION_MOVE:
						final float xDistance = event.getX() - downX;
						final float yDistance = event.getY() - downY;
						Log.e("MyTag","移动距离x:y"+xDistance+ "  "+yDistance);
						break;
					case MotionEvent.ACTION_UP:
						break;
				}
				return false;
			}
		});
	}

	View.OnDragListener onDragListener1 = new View.OnDragListener() {
		@Override
		public boolean onDrag(View view, DragEvent dragEvent) {
			Log.i(TAG, "container.onDrag called======");
			switch (dragEvent.getAction()) {
				case DragEvent.ACTION_DRAG_STARTED://开始.当有view被拖的时候收到此事件
					break;
				case DragEvent.ACTION_DRAG_ENTERED://进入.当被拖view手指按压的位置进入本view的瞬间收到此事件
					Log.e("MyTag","开始");
					if (viewCover==null||viewCover != view ){
						viewCover = view;
					}
					break;
				case DragEvent.ACTION_DRAG_LOCATION://位于.当被拖view手指按压的位置在本view上方的时候收到此事件
						if (viewCover==null||viewCover != view ){
							viewCover = view;
							draggingView = (View) dragEvent.getLocalState();
							//当前容器
							thisContainer = ((ViewGroup) view);
							//被拖拽view覆盖的view
							coveredView = thisContainer.getChildAt(0);
							draggingViewContainer = (ViewGroup) draggingView.getParent();
//							Log.e(TAG, "位于:"+viewCover.getId()+"   draggingView:"+draggingView.getId()+"  coveredView:"+coveredView.getId());
							if(draggingView != coveredView && NoMove(thisContainer)){
//								thisContainer.clearAnimation();
//								thisContainer.startAnimation(aset_4);

							}else if(draggingView != coveredView){
//								thisContainer.clearAnimation();
//								thisContainer.startAnimation(animDown);
//								draggingViewContainer.clearAnimation();
//								draggingViewContainer.startAnimation(animDown);
							}

						}
					break;
				case DragEvent.ACTION_DROP://丢入.当被拖view在本view上方手指释放开,收到此事件
//                        Log.i(TAG, "丢入");
					Log.i(TAG, "丢入view_container2");
					//此时dragEvent里包含要被拖view
					draggingView = (View) dragEvent.getLocalState();
					//当前容器
					thisContainer = ((ViewGroup) view);
					draggingView.setVisibility(View.VISIBLE);
					//被拖拽view覆盖的view
					coveredView = thisContainer.getChildAt(0);
					//当拖拽的view跟被覆盖的view不同时
					if (draggingView != coveredView  && NoMove(thisContainer)) {
						draggingViewContainer = (ViewGroup) draggingView.getParent();
						//两个容器交换子view
//						thisContainer.removeView(coveredView);
//						draggingViewContainer.removeView(draggingView);
//						thisContainer.addView(draggingView);
//						draggingViewContainer.addView(coveredView);
//						moveToWord(thisContainer,draggingViewContainer);
//						moveToWord(draggingViewContainer,thisContainer);

						changeToView(draggingViewContainer,thisContainer,0);
//						thisContainer.startAnimation(aset_4);
					}else if (draggingView != coveredView&&!NoMove(thisContainer)){
						if (!isThis(draggingViewContainer,thisContainer)){

						}else if (getIsClose(draggingViewContainer)){
							openView(draggingView,draggingViewContainer);
						}else{
							closeView(draggingView,draggingViewContainer);
						}


					}
					break;
				case DragEvent.ACTION_DRAG_EXITED://出去.当被拖view手指按压位置从本view拖出去收到此事件
                        Log.e(TAG, "出去");
					break;
				case DragEvent.ACTION_DRAG_ENDED://结束.手指释放拖拽结束收到此事件.
//                        Log.i(TAG, "结束");
					draggingView = (View) dragEvent.getLocalState();
					//当前容器
					thisContainer = ((ViewGroup) view);
					//被拖拽view覆盖的view
					coveredView = thisContainer.getChildAt(0);
					draggingView.setVisibility(View.VISIBLE);
					draggingViewContainer = (ViewGroup) draggingView.getParent();
					if (draggingView == coveredView){
//						animDown= new TranslateAnimation(0, 0, 0, 20);
//						animDown.setDuration(400);
//						animDown.setRepeatCount(0);//动画的反复次数
//						animDown.setFillAfter(true);//设置为true，动画转化结束后被应用
//						thisContainer.startAnimation(animDown);
					}
					break;
				default:
					break;
			}
			//一定要为true
			return true;
		}
	};

	private boolean isThis(ViewGroup viewGroup,ViewGroup viewGroup2){
		boolean isClose = false;
		for (ListBean bean:beanList){
			if (bean.getView() == viewGroup){
				if (list.get(bean.getNum()) == viewGroup2){
					isClose =true;
				}
			}
		}
		return isClose;
	}

	private boolean getIsClose(ViewGroup viewGroup){
		boolean isClose = false;
		for (ListBean bean:beanList){
			if (bean.getView() == viewGroup){
				isClose = bean.isStatus();
			}
		}
		return isClose;
	}

	private void closeView(View v,ViewGroup viewGroup){
		v.clearAnimation();
		animUp= new TranslateAnimation(0, 0, 0, -20);
		animUp.setDuration(400);
		animUp.setRepeatCount(0);//动画的反复次数
		animUp.setFillAfter(false);//设置为true，动画转化结束后被应用
		animUp.setAnimationListener(new Animation.AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {

			}

			@Override
			public void onAnimationEnd(Animation animation) {

				LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) v.getLayoutParams();
				layoutParams.topMargin = -20;
				layoutParams.bottomMargin = -20;
				layoutParams.height = 260;
				v.setLayoutParams(layoutParams);
				for (ListBean bean:beanList){
					if (bean.getView() == viewGroup){
						addView(list.get(bean.getNum()),v,(ViewGroup)list.get(bean.getNum()).getParent(),viewGroup,
								viewList.get(bean.getNum()));
						bean.setStatus(true);
					}
				}

			}

			@Override
			public void onAnimationRepeat(Animation animation) {

			}
		});
		v.startAnimation(animUp);
	}

	private void openView(View v,ViewGroup viewGroup){
		v.clearAnimation();
		animDown.setAnimationListener(new Animation.AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {

			}

			@Override
			public void onAnimationEnd(Animation animation) {

				LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) v.getLayoutParams();
				layoutParams.topMargin = 20;
//				layoutParams.bottomMargin = v.getBottom()+20;
				layoutParams.height = 260;
				v.setLayoutParams(layoutParams);
				for (ListBean bean:beanList){
					if (bean.getView() == viewGroup){
						bean.setStatus(false);
					}
				}

			}

			@Override
			public void onAnimationRepeat(Animation animation) {

			}
		});
		v.startAnimation(animDown);
	}

	//交换2个view
	private void changeToView(ViewGroup v1p,ViewGroup v2p,int time){

		int num;
		for (ListBean b:beanList){
			if (b.getView().getId() == v1p.getId()){
				num = b.getNum();
				for (ListBean b2:beanList){
					if (b2.getView().getId() == v2p.getId()){
						b.setNum(b2.getNum());
						b2.setNum(num);
					}
				}
			}
		}
		moveToWord(v2p,v1p,time);
		moveToWord2(v1p,v2p,time);
	}

	void addView(View v1,View v2,ViewGroup v1p,ViewGroup v2p,LinearLayout llShow){

		v1p.removeView(v1);
		v2p.removeView(v2);

		llShow.addView(v2);
		animUp= new TranslateAnimation(0, 0, 0, -20);
		animUp.setDuration(0);
		animUp.setRepeatCount(0);//动画的反复次数
		animUp.setFillAfter(true);//设置为true，动画转化结束后被应用
		v2.startAnimation(animUp);
		llShow.setVisibility(View.VISIBLE);
		ll_move.setVisibility(View.VISIBLE);
		ll_move.clearAnimation();
		llShow.clearAnimation();

		animation4.setAnimationListener(new Animation.AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {

			}

			@Override
			public void onAnimationEnd(Animation animation) {
//				ll_2.removeView(v1);
				ll_move.clearAnimation();
				llShow.removeView(v2);
//
				v1p.addView(v1);
				v2p.addView(v2);
				llShow.setVisibility(View.INVISIBLE);
				ll_move.setVisibility(View.GONE);
			}

			@Override
			public void onAnimationRepeat(Animation animation) {

			}
		});
		llShow.startAnimation(animation4);
	}

//颤抖动画
	private void startShakeByPropertyAnim(View view, float scaleSmall, float scaleLarge, float shakeDegrees, long duration) {
		if (view == null) {
			return;
		}
		//TODO 验证参数的有效性

		//先变小后变大
		PropertyValuesHolder scaleXValuesHolder = PropertyValuesHolder.ofKeyframe(View.SCALE_X,
				Keyframe.ofFloat(0f, 1.0f),
				Keyframe.ofFloat(0.25f, scaleSmall),
				Keyframe.ofFloat(0.5f, scaleLarge),
				Keyframe.ofFloat(0.75f, scaleLarge),
				Keyframe.ofFloat(1.0f, 1.0f)
		);
		PropertyValuesHolder scaleYValuesHolder = PropertyValuesHolder.ofKeyframe(View.SCALE_Y,
				Keyframe.ofFloat(0f, 1.0f),
				Keyframe.ofFloat(0.25f, scaleSmall),
				Keyframe.ofFloat(0.5f, scaleLarge),
				Keyframe.ofFloat(0.75f, scaleLarge),
				Keyframe.ofFloat(1.0f, 1.0f)
		);

		//先往左再往右
		PropertyValuesHolder rotateValuesHolder = PropertyValuesHolder.ofKeyframe(View.ROTATION,
				Keyframe.ofFloat(0f, 0f),
				Keyframe.ofFloat(0.1f, -shakeDegrees),
				Keyframe.ofFloat(0.2f, shakeDegrees),
				Keyframe.ofFloat(0.3f, -shakeDegrees),
				Keyframe.ofFloat(0.4f, shakeDegrees),
				Keyframe.ofFloat(0.5f, -shakeDegrees),
				Keyframe.ofFloat(0.6f, shakeDegrees),
				Keyframe.ofFloat(0.7f, -shakeDegrees),
				Keyframe.ofFloat(0.8f, shakeDegrees),
				Keyframe.ofFloat(0.9f, -shakeDegrees),
				Keyframe.ofFloat(1.0f, 0f)
		);

		ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(view, scaleXValuesHolder, scaleYValuesHolder, rotateValuesHolder);
		objectAnimator.setDuration(duration);
		objectAnimator.start();
	}

	private boolean NoMove(View v){
		boolean isMove = true;
		for (View view:list){
			if (v.getId()==view.getId()){
				isMove =  false;
			}
		}
		return isMove;
	}

	private void moveViewToTargetView(View view, View targetView) {
		final float x = view.getX();
		final float y = view.getY();

		final float targetX = targetView.getX();
		final float targetY = targetView.getY();
		view.animate()
				.translationX(-(x - targetX))
				.translationY(-(y- targetY))
				.setDuration(800)
				.setInterpolator(new DecelerateInterpolator())
				.withLayer()
				.start();

//		moveToWord(view, targetView);
	}

	private void moveToWord(View view, View targetView,int time) {
		final float x = view.getX();
		final float y = view.getY();

		final float targetX = targetView.getX();
		final float targetY = targetView.getY();
		ValueAnimator valueAnimator = new ValueAnimator();
		valueAnimator.setDuration(time);//600
		valueAnimator.setObjectValues(new PointF(x, y));
		valueAnimator.setInterpolator(new DecelerateInterpolator());
		//首先判断 目标点在上还是在下
		final boolean flagX = ((x - targetX) > 0) ? true : false;
		final boolean flagY = ((y - targetY) > 0) ? true : false;
		valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {
			@Override
			public PointF evaluate(float fraction, PointF startValue,
								   PointF endValue) {
				//从0.0 --->>   1.0
				PointF point = new PointF();
				//这里是需要倒着来  最后要到达200 200 这个点

				float fractionNeed = 1 - fraction;

				if (flagX) {
					float vX = x - targetX;
					point.x = vX * fractionNeed + targetX;
				} else {
					float vX = targetX - x;
					point.x = x + vX * fraction;
				}

				if (flagY) {
					float vY = y - targetY;
					point.y = vY * fractionNeed + targetY;
				} else {
					float vY = targetY - y;
					point.y = y + vY * fraction;
				}
				return point;

			}
		});
		valueAnimator.start();
		valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				PointF point = (PointF) animation.getAnimatedValue();
				float vX = point.x;
				float vY = point.y;
				//说明vx 最大值就是view原坐标
				if (flagX) {
					if (vX <= x && vX >= targetX) {
						view.setX(vX);
					}
				} else {//说明vx 最小值就是view原坐标
					if (vX >= x && vX <= targetX) {
						view.setX(vX);
					}
				}

				//说明vY 最大值就是view原坐标
				if (flagY) {
					if (vY <= y && vY >= targetY) {
						view.setY(vY);
					}
				} else {//说明vx 最小值就是view原坐标
					if (vY >= y && vY <= targetY) {
						view.setY(vY);
					}
				}
			}
		});
	}

	private void moveToWord2(View view, View targetView,int time) {
		final float x = view.getX();
		final float y = view.getY();

		final float targetX = targetView.getX();
		final float targetY = targetView.getY();
		ValueAnimator valueAnimator = new ValueAnimator();
		valueAnimator.setDuration(time);//600
		valueAnimator.setObjectValues(new PointF(x, y));
		valueAnimator.setInterpolator(new DecelerateInterpolator());
		//首先判断 目标点在上还是在下
		final boolean flagX = ((x - targetX) > 0) ? true : false;
		final boolean flagY = ((y - targetY) > 0) ? true : false;

		valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {

			@Override
			public PointF evaluate(float fraction, PointF startValue,
								   PointF endValue) {
				//从0.0 --->>   1.0

				PointF point = new PointF();
				//这里是需要倒着来  最后要到达200 200 这个点

				float fractionNeed = 1 - fraction;

				if (flagX) {
					float vX = x - targetX;
					point.x = vX * fractionNeed + targetX;
				} else {
					float vX = targetX - x;
					point.x = x + vX * fraction;
				}

				if (flagY) {
					float vY = y - targetY;
					point.y = vY * fractionNeed + targetY;
				} else {
					float vY = targetY - y;
					point.y = y + vY * fraction;
				}
				return point;

			}
		});
		valueAnimator.addListener(new Animator.AnimatorListener() {
			@Override
			public void onAnimationStart(Animator animator) {

			}

			@Override
			public void onAnimationEnd(Animator animator) {
				handler.sendEmptyMessage(1);
			}

			@Override
			public void onAnimationCancel(Animator animator) {

			}

			@Override
			public void onAnimationRepeat(Animator animator) {

			}
		});
		valueAnimator.start();
		valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				PointF point = (PointF) animation.getAnimatedValue();
				float vX = point.x;
				float vY = point.y;
				//说明vx 最大值就是view原坐标
				if (flagX) {
					if (vX <= x && vX >= targetX) {
						view.setX(vX);
					}
				} else {//说明vx 最小值就是view原坐标
					if (vX >= x && vX <= targetX) {
						view.setX(vX);
					}
				}

				//说明vY 最大值就是view原坐标
				if (flagY) {
					if (vY <= y && vY >= targetY) {
						view.setY(vY);
					}
				} else {//说明vx 最小值就是view原坐标
					if (vY >= y && vY <= targetY) {
						view.setY(vY);
					}
				}
			}
		});
	}


}
