using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 1.插值 某个数值 。   2.生成动画。  （开始 动画的回调 ,完成动画的回调）     3.关闭动画 
namespace ScrollViewUI
{
    public enum EaseType
    {
        Normal
    }


    public class DGTween
    {
        public Action actStartFun = null;
        public Action actFinishFun = null;
        public EaseType type = EaseType.Normal;
        public IEnumerator ienumLerp;
        public bool isKill;
    }
    public static class DGTweenSystem
    {
        public static DGTween SetEase(this DGTween self, EaseType type)
        {
            self.type = type;
            return self;
        }
        public static DGTween OnStart(this DGTween self, Action actStartFun)
        {
            self.actStartFun = actStartFun;
            return self;
        }

        public static DGTween OnComplete(this DGTween self, Action actFinishFun)
        {
            self.actFinishFun = actFinishFun;
            return self;
        }


    }
    public class DOTweenAnimCurve : MonoBehaviour
    {
        private static object lockHelp = new object();
        private static DOTweenAnimCurve _instance;
        public static DOTweenAnimCurve Instance
        {
            get
            {
                lock (lockHelp)
                {
                    if (_instance == null)
                    {

                        GameObject go = new GameObject("DOTweenAnimCurve");
                        _instance = go.AddComponent<DOTweenAnimCurve>();
                        _instance.Init();
                        DontDestroyOnLoad(go);

                    }
                }
                return _instance;

            }
        }


        //0-1的变动

        public Dictionary<EaseType, AnimationCurve> animCurveDic = new Dictionary<EaseType, AnimationCurve>();
        public void Init()
        {

            animCurveDic.Add(EaseType.Normal, AnimCurve_Normal());

        }
        #region 曲线

        public AnimationCurve AnimCurve_Normal()
        {
            AnimationCurve animCurve = new AnimationCurve();
            animCurve.AddKey(0, 0);
            animCurve.AddKey(1, 1);

            return animCurve;
        }


        #endregion

        #region 移动 动画

        public DGTween DOAnchorPosY(RectTransform rtf, float endV, float time)
        {
            //TODO: DGTween 对象池子生成。 回收要重置
            return To(rtf.anchoredPosition.y, endV, time, progress =>
            {

                rtf.anchoredPosition = new Vector2(rtf.anchoredPosition.x, progress);

            });
        }
        public DGTween DOAnchorPosX(RectTransform rtf, float endV, float time)
        {
            //TODO: DGTween 对象池子生成。 回收要重置
            return To(rtf.anchoredPosition.x, endV, time, progress =>
            {

                rtf.anchoredPosition = new Vector2(progress, rtf.anchoredPosition.y);

            });
        }
        #endregion


        public DGTween To(float startV, float endV, float time, Action<float> actUpdateFun)
        {
            //TODO: DGTween 对象池子生成。 回收要重置
            DGTween animCurveClass = new DGTween();
            animCurveClass.ienumLerp = StartLerp(animCurveClass, startV, endV, time, actUpdateFun);
            StartCoroutine(animCurveClass.ienumLerp);

            return animCurveClass;
        }

        public void KillAnimCurve(DGTween animCurve)
        {
            if (!animCurve.isKill && animCurve.ienumLerp != null)
            {
                StopCoroutine(animCurve.ienumLerp);
            }
            animCurve.ienumLerp = null;
        }

        IEnumerator StartLerp(DGTween ani, float startV, float endV, float time, Action<float> actUpdateFun)
        {
            float aa = 0;
            AnimationCurve trt = animCurveDic[ani.type];
            yield return null;
            ani.actStartFun?.Invoke();

            while (aa < time)
            {
                aa += Time.deltaTime;

                float ass = trt.Evaluate(aa / time);

                float curV = Mathf.Lerp(startV, endV, ass);
                actUpdateFun?.Invoke(curV);

                yield return null;

            }

            actUpdateFun?.Invoke(endV);
            ani.actFinishFun?.Invoke();
            ani.isKill = true;
        }

    }

}
