// Attach to an empty game object in the scene
using UnityEngine;
using UnityEngine.Events;

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

public class EventManager : MonoBehaviour
{

    private Dictionary<string, UnityEvent> eventDictionary;

    private static EventManager eventManager;

    public static EventManager instance
    {
        get
        {
            // if there is no instance of the event manager in the scene
            if (!eventManager)
            {
                // Search for an instance in the scene
                eventManager = FindObjectOfType(typeof(EventManager)) as EventManager;

                // if no instance is still found
                if (!eventManager)
                {
                    Debug.LogError("No event manager found in the heirarchy");
                }
                else // if instance has been found, initialize event manager
                {
                    eventManager.Initialize();
                }
            }
            return eventManager;
        }
    }

    void Initialize()
    {
        // initialize an instance
        if (eventDictionary == null)
        {
            eventDictionary = new Dictionary<string, UnityEvent>();
        }
    }


    // Adds a listener to the event
    public static void StartListening(string eventName, UnityAction listener)
    {
        UnityEvent thisEvent = null;
        // if key value pair is found, add listener
        // else create a new UnityEvent, add a listener, and push to Dictionary
        if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
        {
            thisEvent.AddListener(listener);
        }
        else
        {
            thisEvent = new UnityEvent();
            thisEvent.AddListener(listener);
            instance.eventDictionary.Add(eventName, thisEvent);
        }
    }

    // Removes listener to the event
    public static void StopListening(string eventName, UnityAction listener)
    {
        if (eventManager == null) return;

        UnityEvent thisEvent = null;

        if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
        {
            thisEvent.RemoveListener(listener);
        }
    }

    public static void TriggerEvent(string eventName)
    {
        UnityEvent thisEvent = null;
        if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
        {
            thisEvent.Invoke();
        }
    }
}