using System;
using UnityEngine;
using UnityEngine.Events;

[RequireComponent(typeof(Animator)), DisallowMultipleComponent]
public sealed class AnimationEventReceiver : MonoBehaviour {

    [SerializableAttribute]
    private class FilenameArray {
        [SerializeField]
        private string[] stringArray = default;
        public string GetRandom(){
            return stringArray.RandomChoose();
        }
    }

    [SerializeField]
    private int randomIntMin = 0;
    [SerializeField]
    private int randomIntMax = 0;

    [SerializeField]
    private FilenameArray[] randomPlaySEFilenames = default;
    [SerializeField]
    private FilenameArray[] randomPlayVoiceFilenames = default;

    public UnityEvent onEvent1 = default;
    public UnityEvent onEvent2 = default;
    public UnityEvent onEvent3 = default;

    [SerializeField]
    private UnityEvent[] eventArray = default;

    private Animator animator;
    private int randomIntHash = Animator.StringToHash("RandomInt");

    void Awake(){
        animator = GetComponent<Animator>();
    }

    public void OnEvent1(){
        try{
            onEvent1.Invoke();
        }catch(IndexOutOfRangeException e){
            string path = this.gameObject.name;
            Transform parent = this.transform.parent;
            while(parent != null){
                path = parent.name + "/" + path;
                parent = parent.parent;
            }
            throw new Exception(path + " " + e.ToString());
        }
    }
    public void OnEvent2(){
        onEvent2.Invoke();
    }
    public void OnEvent3(){
        onEvent3.Invoke();
    }

    public void OnEventArray(int index){
#if UNITY_EDITOR
        if(index < 0){
            Debug.LogError(string.Format("{0} の OnEventArray に0未満の数値を指定しないで下さい。", transform.GetPath()));
            UnityEditor.EditorApplication.isPlaying = false;
        }else if(index >= eventArray.Length){
            Debug.LogError(string.Format("{0} の OnEventArray は {0} までしかありません", transform.GetPath(), eventArray.Length - 1));
            UnityEditor.EditorApplication.isPlaying = false;
        }
#endif
        eventArray[index].Invoke();
    }

    public void OnRandomInt(){
        animator.SetInteger(randomIntHash, UnityEngine.Random.Range(randomIntMin, randomIntMax));
    }

    public void OnPlaySE(string filename){
        SoundManager.Instance.PlaySE(string.Format("Sounds/SE/{0}", filename));
    }
    public void OnPlaySEMaxCount(AnimationEvent animationEvent){
        string filename = animationEvent.stringParameter;
        int maxCount = animationEvent.intParameter;
        SoundManager.Instance.PlaySE(string.Format("Sounds/SE/{0}", filename), maxCount);
    }
    public void OnPlaySEVolume(AnimationEvent animationEvent){
        string filename = animationEvent.stringParameter;
        float volume = animationEvent.floatParameter;
        SoundManager.Instance.PlaySE(string.Format("Sounds/SE/{0}", filename), 0, volume);
    }
    public void OnPlayRandomSE(int index){
        if(randomPlaySEFilenames.Length <= index) return ;
        SoundManager.Instance.PlaySE(string.Format("Sounds/SE/{0}", randomPlaySEFilenames[index].GetRandom()));
    }

    public void OnPlayVoice(string filename){
        SoundManager.Instance.PlayVoice(string.Format("Sounds/VOICE/{0}", filename));
    }
    public void OnPlayVoiceMaxCount(AnimationEvent animationEvent){
        string filename = animationEvent.stringParameter;
        int maxCount = animationEvent.intParameter;
        SoundManager.Instance.PlayVoice(string.Format("Sounds/VOICE/{0}", filename), maxCount);
    }
    public void OnPlayVoiceVolume(AnimationEvent animationEvent){
        string filename = animationEvent.stringParameter;
        float volume = animationEvent.floatParameter;
        SoundManager.Instance.PlayVoice(string.Format("Sounds/VOICE/{0}", filename), 0, volume);
    }
    public void OnPlayRandomVoice(int index){
        if(randomPlayVoiceFilenames.Length <= index) return ;
        SoundManager.Instance.PlayVoice(string.Format("Sounds/VOICE/{0}", randomPlayVoiceFilenames[index].GetRandom()));
    }

    public void OnPlayVibrationOnce(){
        VibrationManager.Instance.PlayVibrationOnce();
    }
    public void OnPlayVibrationOnceStrong(){
        VibrationManager.Instance.PlayVibrationOnceStrong();
    }
    public void OnPlayVibrationOnceWeak(){
        VibrationManager.Instance.PlayVibrationOnceWeak();
    }
    public void OnPlayVibrationDoubleStrong(){
        VibrationManager.Instance.PlayVibrationDoubleStrong();
    }
    public void OnPlayVibrationDoubleWeak(){
        VibrationManager.Instance.PlayVibrationDoubleWeak();
    }
    public void OnPlayVibrationTriple(){
        VibrationManager.Instance.PlayVibrationTriple();
    }

    public void DestroyObject(){
        Destroy(gameObject);
    }

    public void DisableObject(){
        gameObject.SetActive(false);
    }
}
