using UnityEngine;
using System.Collections.Generic;

namespace mgaia.Utils
{
    /// <summary>
    /// Extensões para cuidar da classe Transform
    /// </summary>
    public static class TransformExtensions
    {
        /// <summary>
        /// Retorna todas as transform filhas de um transform
        /// </summary>
        /// <owner>Felipe</owner>
        public static IEnumerable<Transform> GetChildren(this Transform parent)
        {
            Assert.AssertTrue(parent != null, "'parent' must be non null");

            return IEnumerableExtensions.Range(0, parent.childCount) // De 0 - (childCount - 1)
                .Select((idx) => parent.GetChild(idx)); // Pegue o filho em idx
        }

        /// <summary>
        /// Retorna todos os bounds dos transforms
        /// </summary>
        /// <owner>Felipe</owner>
        public static IEnumerable<Bounds> GetBounds(this IEnumerable<Transform> transforms)
        {
            foreach (Transform t in transforms)
            {
                MeshFilter mf = t.GetComponent<MeshFilter>();
                if (mf == null || mf.sharedMesh == null || mf.sharedMesh.vertices == null || mf.sharedMesh.vertices.Length == 0)
                {
                    continue;
                }
                Bounds current = new Bounds(t.TransformPoint(mf.sharedMesh.vertices[0]), Vector3.zero);
                // foreach encapsula todos os pontos da malha em uma estrutura de bounds
                foreach (var v in mf.sharedMesh.vertices) { current.Encapsulate(t.TransformPoint(v)); }
                yield return current;
            }
        }

        /// <summary>
        /// Retorna o transform raiz do objeto
        /// </summary>
        /// <owner>Victor</owner>
        public static Transform GetRoot(this Transform transform)
        {
            Transform currentTransform = transform;
            while (currentTransform.parent != null)
            {
                currentTransform = currentTransform.parent;
            }

            return currentTransform;
        }

		/// <summary>
		/// Procura um transform filho
		/// </summary>
		/// <owner>Victor</owner>
		public static Transform FindChild(this Transform transform, string name, bool recursively)
		{
			if (recursively)
			{
				return FindOnChildrens(transform, name);
			}
			else
			{
				return transform.FindChild(name);
			}
		}

		/// <summary>
		/// Procura recursivamente um transform de nome em um array de transforms filhos
		/// </summary>
		/// <owner>Victor</owner>
		private static Transform FindOnChildrens(Transform transform, string name)
		{
			foreach (Transform childTransform in transform.GetChildren())
			{
				if (childTransform.name.Equals(name))
				{
					return childTransform;
				}
				else
				{
					 Transform foundTransform = FindOnChildrens(childTransform, name);

					 if (foundTransform != null)
					 {
						 return foundTransform;
					 }
				}
			}

			return null;
		}
    }
}