
using Sandbox.ModAPI.Ingame;

using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;

using VRage.Game.ModAPI.Ingame;

namespace IngameScript
{
    static class Utils
    {
        /// <summary>
        /// Get the first terminal block matching the given name or null if nothing is found.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="gridTerminal"></param>
        /// <param name="name"></param>
        /// <param name="grid"></param>
        /// <returns></returns>
        public static T GetBlock<T>(this IMyGridTerminalSystem gridTerminal, string name = null, IMyCubeGrid grid = null)
            where T: class, IMyTerminalBlock
        {
            return Utils.GetBlocks<T>(gridTerminal, name, grid).FirstOrDefault();
        }

        /// <summary>
        /// Get all terminal blocks matching the given name.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="gridTerminal"></param>
        /// <param name="name"></param>
        /// <param name="grid"></param>
        /// <returns></returns>
        public static IEnumerable<T> GetBlocks<T>(this IMyGridTerminalSystem gridTerminal, string name = null, IMyCubeGrid grid = null)
            where T : class, IMyTerminalBlock
        {
            var l = new List<T>();
            gridTerminal.GetBlocksOfType(l, (T block) =>
                (name == null || block.CustomName == name) && (grid == null || block.CubeGrid == grid)
            );
            return l;
        }

        /// <summary>
        /// Get all groups matching the given name.
        /// </summary>
        /// <param name="gridTerminal"></param>
        /// <param name="groupName"></param>
        /// <param name="grid"></param>
        /// <returns></returns>
        public static IEnumerable<IMyBlockGroup> GetBlockGroups(this IMyGridTerminalSystem gridTerminal, string groupName = null, IMyCubeGrid grid = null)
        {
            var groups = new List<IMyBlockGroup>();
            gridTerminal.GetBlockGroups(
                groups,
                group =>
                {
                    if (groupName != null && group.Name != groupName)
                        return false;
                    if (grid == null)
                        return true;
                    var l = new List<IMyTerminalBlock>();
                    group.GetBlocks(l, block => block.CubeGrid == grid);
                    return l.Count > 0;
                }
            );
            return groups;
        }

        /// <summary>
        /// Get all terminal blocks owned by the first given group name.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="gridTerminal"></param>
        /// <param name="groupName"></param>
        /// <param name="grid"></param>
        /// <returns></returns>
        public static IEnumerable<T> GetBlocksFromGroup<T>(this IMyGridTerminalSystem gridTerminal, string groupName = null, IMyCubeGrid grid = null)
            where T : class, IMyTerminalBlock
        {
            foreach (var group in gridTerminal.GetBlockGroups(groupName, grid))
            {
                var l = new List<T>();
                group.GetBlocksOfType(l);
                if (l.Count > 0)
                    return l;
            }

            return new List<T>();
        }
    }
}