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

#if UNITY_EDITOR
using UnityEditor;
#endif

[DefaultExecutionOrder(-500)]
public class UnityEventDispatcher : MonoBehaviour
{
    //automatically create UnityEventDispatcher when invoked in any way
    static UnityEventDispatcher()
    {
        //Clean up our instance while inside the Editor to prevent runtime errors
#if UNITY_EDITOR
        EditorApplication.playModeStateChanged += (x) =>
        {
            if (x == PlayModeStateChange.ExitingPlayMode)
            {
                if(instance != null)
                    Destroy(instance);
            }
        };
#endif

        GameObject go = new GameObject("UnityEventDispatcher", typeof(UnityEventDispatcher));
        //hide our shameful disregard of Unity best practices
        go.hideFlags = HideFlags.HideAndDontSave;
    }

    static UnityEventDispatcher instance;

    //main event pumps
    public static event Action OnUpdate = delegate { };
    public static event Action OnFixedUpdate = delegate { };

    //global coroutine helper function
    public static Coroutine StartGlobalCoroutine(IEnumerator coroutine)
    {
        return instance.StartCoroutine(coroutine);
    }

    private void Awake()
    {
        //ensure only one instance exists
        if (instance != null)
        {
            Destroy(gameObject);
            return;
        }

        instance = this;
        DontDestroyOnLoad(gameObject);
    }

    private void Update()
    {
        OnUpdate();
    }

    private void FixedUpdate()
    {
        OnFixedUpdate();
    }
}
