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

namespace BitStrap
{
    /// <summary>
    /// Safe version of System.Action that envelopes each call in a try/catch to prevent
    /// execution flow interruption just because of one bad callback.
    /// </summary>
    public class SafeAction
    {
        private List<Action> actions = new List<Action>();

        /// <summary>
        /// Register a callback.
        /// </summary>
        /// <param name="a"></param>
        public void Register( Action a )
        {
            if( !actions.Contains( a ) )
                actions.Add( a );
        }

        /// <summary>
        /// Unregister a callback.
        /// </summary>
        /// <param name="a"></param>
        public void Unregister( Action a )
        {
            actions.Remove( a );
        }

        /// <summary>
        /// Trigger all callbacks.
        /// </summary>
        public void Call()
        {
            for( int i = 0; i < actions.Count; i++ )
            {
                try
                {
                    if( actions[i] != null )
                        actions[i]();
                }
                catch( Exception e )
                {
                    Debug.LogException( e );
                }
            }
        }
    }

    /// <summary>
    /// Safe version of System.Action[T] that envelopes each call in a try/catch to prevent
    /// execution flow interuption just because of one bad callback.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SafeAction<T>
    {
        private List<Action<T>> actions = new List<Action<T>>();

        /// <summary>
        /// Register a callback.
        /// </summary>
        /// <param name="a"></param>
        public void Register( Action<T> a )
        {
            if( !actions.Contains( a ) )
                actions.Add( a );
        }

        /// <summary>
        /// Unregister a callback.
        /// </summary>
        /// <param name="a"></param>
        public void Unregister( Action<T> a )
        {
            actions.Remove( a );
        }

        /// <summary>
        /// Trigger all callbacks.
        /// </summary>
        /// <param name="p1"></param>
        public void Call( T p1 )
        {
            for( int i = 0; i < actions.Count; i++ )
            {
                try
                {
                    if( actions[i] != null )
                        actions[i]( p1 );
                }
                catch( Exception e )
                {
                    Debug.LogException( e );
                }
            }
        }
    }

    /// <summary>
    /// Safe version of System.Action[T1, T2] that envelopes each call in a try/catch to prevent
    /// execution flow interuption just because of one bad callback.
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    /// <typeparam name="T2"></typeparam>
    public class SafeAction<T1, T2>
    {
        private List<Action<T1, T2>> actions = new List<Action<T1, T2>>();

        /// <summary>
        /// Register a callback.
        /// </summary>
        /// <param name="a"></param>
        public void Register( Action<T1, T2> a )
        {
            if( !actions.Contains( a ) )
                actions.Add( a );
        }

        /// <summary>
        /// Unregister a callback.
        /// </summary>
        /// <param name="a"></param>
        public void Unregister( Action<T1, T2> a )
        {
            actions.Remove( a );
        }

        /// <summary>
        /// Trigger all callbacks.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        public void Call( T1 p1, T2 p2 )
        {
            for( int i = 0; i < actions.Count; i++ )
            {
                try
                {
                    if( actions[i] != null )
                        actions[i]( p1, p2 );
                }
                catch( Exception e )
                {
                    Debug.LogException( e );
                }
            }
        }
    }
}
