using Thousandto.Core.Asset;
using Thousandto.Core.Base;
using Thousandto.Launcher.ExternalLibs;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;

//动作播放器,用于编辑器
[ExecuteAlways]
public class AnimPlayScript : MonoBehaviour
{
#if !FUNCELL_LAUNCHER && UNITY_EDITOR
    //编辑时播放的动作
    public string AnimName = string.Empty;
    private string _frontName = string.Empty;
    private PlayableGraph _graph;
    private AnimationPlayableOutput _outPut;
    private AnimListScript _animScript = null;
    private AnimationClipPlayable _curClipAble;
    private float _clipLength = 0f;
    private float _clipTimer = 0f;
    private AnimInfo _lastInfo = null;
    private bool _isPosChanged = false;

    //编辑器播放动作的功能,提供给美术使用
    private void OnEnable()
    {   
        var animator = GetComponent<Animator>();
        if (animator == null)
            return; 
        
        _frontName = string.Empty;
        _graph = PlayableGraph.Create();
        _outPut = AnimationPlayableOutput.Create(_graph, "output", animator);
        _graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
    }

    public void Play(AnimInfo info)
    {
        if (_lastInfo != info)
        {  
            if (_lastInfo != null)
            {
                _lastInfo.playPos = 0;
                _lastInfo.isPlaying = false;
            }

            _lastInfo = info;

            if (!_graph.IsValid()) return;

          
            if (_lastInfo != null && _lastInfo.clip != null)
            {
                
                if (_curClipAble.IsValid())
                {
                    _curClipAble.Destroy();
                }
                _clipTimer = 0f;
                _clipLength = _lastInfo.clip.length;
                _frontName = _lastInfo.clip.name;
                _lastInfo.clip.legacy = false;
                _curClipAble = AnimationClipPlayable.Create(_graph, _lastInfo.clip);
                _outPut.SetSourcePlayable(_curClipAble);
                _graph.Play();
                _lastInfo.isPlaying = true;
                transform.localPosition += new Vector3(0.00000001f, 0, 0);
                _isPosChanged = true;
            }
            else
            {
               
                if (_curClipAble.IsValid())
                {
                    _curClipAble.Destroy();
                }
                _clipTimer = 0f;
                _frontName = "";
                _clipLength = 0;
            }
        }
    }

    public void ChangePos()
    {
        if (_lastInfo != null && _graph.IsValid())
        {
            _clipTimer = _lastInfo.playPos * _clipLength;
            if (_curClipAble.IsValid())
            {
                _curClipAble.SetTime(_clipTimer);
            }
        }
    }

    public void Stop()
    {   
        if (_lastInfo != null)
        {
            _lastInfo.playPos = 0;
            _lastInfo.isPlaying = false;
        }

        if (_curClipAble.IsValid())
        {
            _curClipAble.Destroy();
        }
        _clipTimer = 0f;
        _frontName = "";
        _clipLength = 0;
        _lastInfo = null;
    }

    public void Update()
    {
        if (_isPosChanged)
        {
            transform.localPosition -= new Vector3(0.00000001f, 0, 0);
            _isPosChanged = false;
        }
        if (_clipLength > 0)
        {
            _clipTimer += Time.deltaTime;
            if (_clipTimer >= _clipLength)
            {
                _clipTimer -= _clipLength;
            }
            if (_curClipAble.IsValid())
            {
                _curClipAble.SetTime(_clipTimer);
            }
            if (_lastInfo != null)
            {
                _lastInfo.playPos = _clipTimer / _clipLength;
            }
        }
    }

    private void OnDisable()
    {
        _frontName = string.Empty;
        _clipTimer = 0f;
        if (_graph.IsValid())
        {
            _graph.Destroy();
        }
    }
#endif
}