﻿using System.Collections.Generic;
using JLGames.RocketDriver.CSharp;
using UnityEngine;

namespace JLGames.RocketDriver.Actions.Animatorx
{
    public class AnimationEventInvoker : MonoBehaviour
    {
        public const string FunctionName = "InvokeCall";

        [SerializeField] private bool m_InvokerEnabled = true;

        private readonly Dictionary<string, Callback> m_CallMap = new Dictionary<string, Callback>();

        private void OnDestroy()
        {
            m_CallMap.Clear();
        }

        /// <summary>
        /// Set whether Invoker is enabled or not
        /// 设置Invoker启用与否
        /// </summary>
        /// <param name="invokerEnabled"></param>
        public void SetInvokerEnabled(bool invokerEnabled)
        {
            m_InvokerEnabled = invokerEnabled;
        }

        /// <summary>
        /// Add a callback to the CallMap.
        /// 添加回调
        /// </summary>
        /// <param name="callName"></param>
        /// <param name="func"></param>
        public void AddEventCall(string callName, Callback.Func func)
        {
            if (string.IsNullOrEmpty(callName) || null == func) return;
            m_CallMap.Add(callName, new Callback(func));
        }

        /// <summary>
        /// Add a callback to the CallMap.
        /// 添加回调
        /// </summary>
        /// <param name="callName"></param>
        /// <param name="callback"></param>
        public void AddEventCall(string callName, Callback callback)
        {
            if (string.IsNullOrEmpty(callName) || null == callback) return;
            m_CallMap.Add(callName, callback);
        }

        /// <summary>
        /// Remove a callbak from the CallMap
        /// 移除回调
        /// </summary>
        /// <param name="callName"></param>
        public void RemoveEventCall(string callName)
        {
            if (!m_CallMap.ContainsKey(callName)) return;
            m_CallMap.Remove(callName);
        }

        /// <summary>
        /// This function is called by the frame event in AnimationClip, the parameter is string
        /// 本函数由AnimationClip中的帧事件调用，参数为string
        /// </summary>
        /// <param name="callName"></param>
        public void InvokeCall(string callName)
        {
            if (!m_InvokerEnabled || !m_CallMap.ContainsKey(callName)) return;
            m_CallMap[callName].Invoke();
        }

        /// <summary>
        /// Try to add an AnimationEventInvoker component to the object and return it, ignore and return the existing AnimationEventInvoker component if it exists
        /// 尝试给对象添加一个AnimationEventInvoker组件并返回，如果存在则忽略并返回已存在的AnimationEventInvoker组件
        /// </summary>
        /// <param name="gameObject"></param>
        /// <returns></returns>
        public static AnimationEventInvoker TryAddInvoker(GameObject gameObject)
        {
            var rs = gameObject.GetComponent<AnimationEventInvoker>();
            if (null != rs) return rs;
            return gameObject.AddComponent<AnimationEventInvoker>();
        }
    }
}