using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using MPStudioManagers;
using UnityEngine;
using UnityEngine.Events;

namespace MPStudio
{
    [DisallowMultipleComponent]
    [DefaultExecutionOrder(-1)]
    public class ToolManager : MonoBehaviour
    {
        public static ToolManager Inst { get; private set; }
        
        protected virtual  void Awake()
        {
            if (Inst == null)
            {
                Inst = this;
            }
            else if (Inst != this)
            {
                Destroy(gameObject);
            }
        }
        
        protected virtual void Start()
        {

           // this.TestWeight();
        }

        void TestWeight()
        {
            Weight<string> w = new Weight<string>(new List<int>() { 1, 1, 2 }, new List<string>() { "a", "b", "c" });

            for (int i = 0; i < 100; i++)
            {
                print(w.GetRandomItem());
            }
        }

        void testFunc()
        {
            ToolManager.Delay(this,2f, () =>
            {
                print(Time.time);
            });
        }
        
        public static void Delay(MonoBehaviour mono, float second, UnityAction action)
        {
            IEnumerator delay()
            {
                yield return new WaitForSeconds(second);
                action?.Invoke();
            }

            mono.StartCoroutine(delay());
        }


        
        public static T FindComponent<T>(MonoBehaviour mono, string targetName) where T : Component
        {
            Transform FindTrans(Transform aParent, string aName)
            {
                foreach (Transform child in aParent)
                {
                    if (child.name == aName) return child;

                    if (child.name.Contains("GameObject") && (child.name.StartsWith("GameObject") == false))
                    {
                    }
                    else
                    {
                        var result = FindTrans(child, aName);
                        if (result != null) return result;
                    }
                }

                return null;
            }

            var t = FindTrans(mono.transform, targetName);
            return t != null ? t.GetComponent<T>() : default;
        }
        
        
        
        public static Transform[] GetChildArray(Transform t)
        {
            var res = new Transform[t.childCount];

            for (var i = 0; i < res.Length; i++) res[i] = t.GetChild(i);

            return res;
        }

        public static Transform LocalReset(Transform t)
        {
            t.localPosition = Vector3.zero;
            t.localRotation = Quaternion.identity;
            t.localScale = Vector3.one;
            return t;
        }
        
        public static RectTransform SetWidth(RectTransform rect, float x)
        {
            var sizeDelta = rect.sizeDelta;
            sizeDelta = new Vector2(x, sizeDelta.y);
            rect.sizeDelta = sizeDelta;
            return rect;
        }

        public static RectTransform SetHeight(RectTransform rect, float y)
        {
            var sizeDelta = rect.sizeDelta;
            sizeDelta = new Vector2(sizeDelta.x, y);
            rect.sizeDelta = sizeDelta;
            return rect;
        }

        public static RectTransform SetPosX(RectTransform rect, float val)
        {
            var anchoredPosition3D = rect.anchoredPosition3D;
            anchoredPosition3D = new Vector3(val, anchoredPosition3D.y, anchoredPosition3D.z);
            rect.anchoredPosition3D = anchoredPosition3D;
            return rect;
        }

        public static RectTransform SetPosY(RectTransform rect, float val)
        {
            var anchoredPosition3D = rect.anchoredPosition3D;
            anchoredPosition3D = new Vector3(anchoredPosition3D.x, val, anchoredPosition3D.z);
            rect.anchoredPosition3D = anchoredPosition3D;
            return rect;
        }
        
        
        
        public static Vector3 GetCursorPos()
        {
            var cursorPos = Camera.main.ScreenToWorldPoint(new Vector3(
                Input.mousePosition.x,
                Input.mousePosition.y,
                -Camera.main.transform.position.z
            ));
            return cursorPos;
        }

    }
}