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

public class RewardAnim : MonoBehaviour {

    [SerializeField]
    AnimationCurve m_CurveToTransit = AnimationCurve.Linear(0, 0, 1, 1);

    [SerializeField]
    AnimationCurve m_CurveToTarget = AnimationCurve.Linear(0,0,1,1);

    // Use this for initialization
    void Start () {
		
	}

    private Action m_OnEnd;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="rect"></param>
    /// <param name="targetPos"></param>
    /// <param name="roundDir">大致方向</param>
    /// <param name="randomRange">中转点随机范围</param>
    /// <param name="time"></param>
    /// <param name="OnEnd"></param>
    public void PlayFlyToAnim(Transform rect,Vector3 targetPos,Vector3 roundDir, float transitPosRange, float time,Action OnEnd)
    {
       // float transitPro = UnityEngine.Random.Range(-randomRange, randomRange);
      //  Vector3 transitCenter = rect.position + (targetPos - rect.position) * transitPro;
        m_OnEnd = OnEnd;
      
       // Debug.LogError("roundDir:"+roundDir);

       
        Vector3 transitPos = Vector3.zero;
        if (roundDir == Vector3.zero)
            transitPos = GetRandomRangePos(rect.position, transitPosRange, transitPosRange);
        else
            transitPos = GetRandomRangePos(rect.position, transitPosRange, roundDir);

        float timeRate = (targetPos - transitPos).magnitude / (targetPos - rect.position).magnitude;
        time *= timeRate;
        StartCoroutine(PlayFlyToAnimAddForce(rect, targetPos, transitPos, time,m_CurveToTransit,m_CurveToTarget));

        Invoke("CallBack",time);
        //Game.Instance.DelayAction(time, OnEnd);
        
    }

    void CallBack()
    {
        m_OnEnd?.Invoke();
    }

    public static IEnumerator PlayFlyToAnimAddForce(Transform rect, Vector3 targetPos, Vector3 transitPos,
        float totalTime, AnimationCurve m_CurveToTransit, AnimationCurve m_CurveToTarget,
        float forceToTargetBegin = 0.1f, float forceToTargetMul = 1.075f, float forceToTransitBegin = .99f,
        float forceToTransitMul = 0.90f)
    {
        return PlayFlyToAnimAddForce(rect, ()=> targetPos,  transitPos,
         totalTime,  m_CurveToTransit,  m_CurveToTarget,
         forceToTargetBegin,  forceToTargetMul,  forceToTransitBegin,
         forceToTransitMul );
    }
    public static IEnumerator PlayFlyToAnimAddForce(Transform rect, Func<Vector3> getTargetPosFunc, Vector3 transitPos, float totalTime, AnimationCurve m_CurveToTransit, AnimationCurve m_CurveToTarget,
        float forceToTargetBegin = 0.1f, float forceToTargetMul = 1.1f, float forceToTransitBegin = 0.1f, float forceToTransitMul = 0.9f)
    {
        if (getTargetPosFunc == null)
        {
            GameDebug.LogError("getTargetPosFunc == null");
            yield break;
        }

        float transitRate = 0.3f;// UnityEngine.Random.Range(0.3f, 0.6f);
        Vector3 beginPos = rect.position;
        float timer = 0;

        float transitTime = totalTime * transitRate;

        float forceToTarget = forceToTargetBegin;
        float forceToTransit = forceToTransitBegin;

        Vector3 realTransitPos = transitPos;
        
        while (timer < totalTime)
        {
            yield return null;

            if (rect == null)
                yield break;

            timer += Time.deltaTime;

            float rate = timer / totalTime;

            if (rate < transitRate)
            {
                float x = rate / transitRate;
                //float y = m_CurveToTransit.Evaluate(x);
                Vector3 pos = Vector3.Lerp(beginPos, transitPos, x);
                pos = Vector3.Lerp(pos, getTargetPosFunc(), forceToTarget * x);
                forceToTarget *= forceToTargetMul;
                rect.position = pos;

                realTransitPos = pos;
                
                //GameDebug.LogError($"realTransitPos:{realTransitPos}  y:{y}  forceToTarget():{forceToTarget}  beginPos:{beginPos}  transitPos:{transitPos}");
            }
            else
            {
                float x = (rate - transitRate) / (1 - transitRate);
                float y = m_CurveToTarget.Evaluate(x);
                Vector3 pos = Vector3.Lerp(realTransitPos, getTargetPosFunc(), y);
                pos = Vector3.Lerp(pos, pos + transitPos - beginPos, forceToTransit * x);
                forceToTransit *= forceToTransitMul;

                rect.position = pos;
                

            }
        }

    }


    /// <summary>
    /// 应用插值公式计算运动轨迹
    /// </summary>
    /// <param name="rect"></param>
    /// <returns></returns>
    IEnumerator PlayFlyToAnimNewTon(Transform rect, Vector3 targetPos, float totalTime, Func<float, float> curveFunc)
    {
        if (rect == null || curveFunc == null)
            yield break;

        float transitRate = UnityEngine.Random.Range(0.3f, 0.6f);

        Vector3 beginPos = rect.position;
        float timer = 0;
        while (timer < totalTime)
        {
            yield return null;
            timer += Time.deltaTime;

            float rate = timer / totalTime;
            float rateInCurve = m_CurveToTarget.Evaluate(rate);
            float x = Mathf.Lerp(beginPos.x, targetPos.x, rateInCurve); 
            float y = curveFunc(x);
            rect.position = new Vector3(x, y, beginPos.z);
        }


    }
    Vector3 GetRandomRangePos(Vector3 pos, float randomRangeM,  Vector3 roundDir)
    {
        //指定方向
        float randomM = UnityEngine.Random.Range(randomRangeM/2f, randomRangeM);
        Vector3 dirRandom = roundDir.normalized * randomM;
        //float minX = (roundDir.x > 0) ? 0 : -randomRangeX;
        //float maxX = (roundDir.x > 0) ? randomRangeX : 0;

        //float minY = (roundDir.y > 0) ? 0 : -randomRangeY;
        //float maxY = (roundDir.y > 0) ? randomRangeY : 0;

        //float randomX = UnityEngine.Random.Range(minX, maxX);
        //float randomY = UnityEngine.Random.Range(minY, maxY);
        //randomPos = pos + new Vector2(randomX, randomY);
        Vector3 randomPos = pos + dirRandom;
        return randomPos;
    }
    /// <summary>
    /// 获取一定范围内随机位置
    /// </summary>
    /// <param name="pos"></param>
    /// <param name="randomRange"></param>
    /// <param name="roundDir">大致方向</param>
    /// <returns></returns>
    Vector2 GetRandomRangePos(Vector2 pos,float randomRangeX, float randomRangeY)
    {
        Vector2 randomPos = Vector2.zero;

        float randomX = UnityEngine.Random.Range(-randomRangeX, randomRangeX);
        float randomY = UnityEngine.Random.Range(-randomRangeY, randomRangeY);
        randomPos = pos + new Vector2(randomX, randomY);
      
        return randomPos;
    }

    private void OnDestroy()
    {
        m_OnEnd = null;

    }

    // Update is called once per frame
    void Update () {
		
	}
}
