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

namespace JamUtils
{
    [DefaultExecutionOrder(ORDER_EXECUTION)]
    public class CustomExecutionOrder : MonoBehaviour
    {
        private const int ORDER_EXECUTION = -98;

        static CustomExecutionOrder _instance;

        public static CustomExecutionOrder Instance
        {
            get
            {
                if (_instance == null)
                {
                    GameObject inst = new GameObject("CustomExecutionOrder");
                    inst.hideFlags = HideFlags.DontSave;
                    DontDestroyOnLoad(inst);

                    _instance = inst.AddComponent<CustomExecutionOrder>();
                }
                return _instance;
            }
        }

        public event Action beforeFixedUpdate;
        public event Action afterFixedUpdate;

        public event Action beforeUpdate;
        public event Action afterUpdate;

        private void Awake()
        {
            StartCoroutine(WaitForEndOfFrame());
            StartCoroutine(WaitForFixedUpdate());
        }

        private IEnumerator WaitForEndOfFrame()
        {
            while (true)
            {
                yield return new WaitForEndOfFrame();
                if (afterUpdate != null)
                    afterUpdate();
                if (beforeFixedUpdate != null)
                    beforeFixedUpdate();
            }
        }

        private IEnumerator WaitForFixedUpdate()
        {
            while (true)
            {
                yield return new WaitForFixedUpdate();
                if (afterFixedUpdate != null)
                    afterFixedUpdate();
            }
        }

        private void Update()
        {
            if (beforeUpdate != null)
                beforeUpdate();
        }

    }
}