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

public class AnimBase : MonoBehaviour {


    [SerializeField]
    protected AnimationCurve m_Curve = AnimationCurve.EaseInOut(0, 0, 1, 1);

    public void SetCurve(AnimationCurve _curve)
    {
        m_Curve = _curve;
    }
    
    private DelayAction m_DelayAction;
    public DelayAction delayAction
    {
        get
        {
            if (m_DelayAction == null)
            {
                m_DelayAction = gameObject.AddComponent<DelayAction>();
            }
            return m_DelayAction;
        }
    }

    protected Coroutine PlayAnim<T>(T targetValue, float time, Func<T, T, float, T> lerpFunc, Action<T> setCurValueAction, Func<T> getCurValueFunc, Action callback,bool ensureCallback = true)
    {
        if (gameObject.activeInHierarchy)
        {
            if (ensureCallback)
            {
                delayAction.DelayDoAction(time, callback);
                return StartCoroutine(PlayAnimCoroutine(targetValue, time, lerpFunc, setCurValueAction, getCurValueFunc,null));
            }
            else
            {
                return StartCoroutine(PlayAnimCoroutine(targetValue, time, lerpFunc, setCurValueAction, getCurValueFunc, callback));
            }
        }

        return null;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="targetValue"></param>
    /// <param name="time"></param>
    /// <param name="lerpFunc">Lerp函数</param>
    /// <param name="setCurValueAction"></param>
    /// <param name="getCurValueFunc"></param>
    /// <param name="callback"></param>
    /// <returns></returns>
    IEnumerator PlayAnimCoroutine<T>(T targetValue, float time, Func<T, T, float, T> lerpFunc, Action<T> setCurValueAction, Func<T> getCurValueFunc,Action onEnd)
    {
        if (setCurValueAction == null || getCurValueFunc == null || lerpFunc == null)
            yield break;
        
        float timer = 0;
        T originalValue = getCurValueFunc();
        while (timer <= time)
        {
            if (!this) yield break;
            
            timer += Time.deltaTime;

            float rate = timer / time;
            float y = m_Curve.Evaluate(rate);

            var curValue = lerpFunc(originalValue, targetValue, y);
            
            setCurValueAction(curValue);
            yield return null;
        }
        onEnd?.Invoke();
    }
    
    public void StopAllAnim()
    {
        StopAllCoroutines();
    }

    private void OnDestroy()
    {
        StopAllAnim();
    }
}
