namespace ChillConnect
{
    using System;
    using FairyGUI;
    using Spine.Unity;
    using UnityEngine;
    using System.Collections.Generic;
    using Object = UnityEngine.Object;

    public class FXManager : BaseUnityManager<FXManager>
    {
        private string fxPath = "Effect/sys/";

        FXPool<Fx_Type> fx_ObjMonoObjPool;

        private Transform goWrapperPar;

        public override void Init()
        {
            base.Init();
            GameObject obj = new GameObject("FX_Pool");
            obj.transform.parent = transform;
            obj.transform.localPosition = Vector3.zero;
            obj.transform.localEulerAngles = Vector3.zero;
            fx_ObjMonoObjPool = new FXPool<Fx_Type>(obj.transform);
            fx_ObjMonoObjPool.NewObjFunc = NewObjFunc;
            fx_ObjMonoObjPool.GetObjFunc = GetObjFunc;
            fx_ObjMonoObjPool.RecObjFunc = RecObjFunc;
        }

        private void RecObjFunc(Fx_Type arg1, Object arg2)
        {
            var componet = arg2 as Component;
            if (componet)
                componet.gameObject.SetActive(false);
            else
            {
                (arg2 as GameObject).SetActive(false);
            }
        }

        private void GetObjFunc(Fx_Type arg1, Object arg2)
        {
            var componet = arg2 as Component;
            if (componet)
                componet.gameObject.SetActive(true);
            else
            {
                (arg2 as GameObject).SetActive(true);
            }
        }


        private Object NewObjFunc(Fx_Type arg)
        {
            if ((int)arg < 100)
            {
                var go = LoadKit.Instance.LoadGameObjectAndCloneSync("Effect.spine." + arg, arg.ToString());
                SkeletonAnimation sk = go.GetComponent<SkeletonAnimation>();

                return sk;
            }
            else
            {
                fxPath = "Effect.sys." + arg;
                var go = LoadKit.Instance.LoadGameObjectAndCloneSync(fxPath, arg.ToString());


                ParticleSystem particleSystem = go.GetComponent<ParticleSystem>();
                if (particleSystem == null)
                {
                    particleSystem = go.GetComponentInChildren<ParticleSystem>();
                }

                if (particleSystem != null)
                {
                    foreach (var item in particleSystem.GetComponentsInChildren<ParticleSystem>())
                    {
                        var main = item.main;
                        main.scalingMode = ParticleSystemScalingMode.Hierarchy;
                    }

                    particleSystem.transform.localScale = Vector3.one * 100;
                    return particleSystem;
                }

                return go;
            }
        }

        public T GetFx<T>(Fx_Type fx_Type) where T : Object
        {
            T obj = fx_ObjMonoObjPool.GetObject<T>(fx_Type);
            SkeletonAnimation ani = obj as SkeletonAnimation;
            if (ani != null)
            {
                ani.gameObject.layer = 0;
                ani.ClearState();
                ani.transform.localPosition = Vector3.zero;
                ani.transform.localEulerAngles = Vector3.zero;
            }

            return obj;
        }

        public void RecFx<T>(Fx_Type fx_Type, T obj) where T : Object
        {
            fx_ObjMonoObjPool.RecObject(fx_Type, obj);
        }

        public List<GameObject> gameObjects = new List<GameObject>();


        public override void Dispose()
        {
            base.Dispose();
            fx_ObjMonoObjPool.Dispose();
        }

        private Queue<GoWrapper> goWrapperQueue = new Queue<GoWrapper>();

        public T SetFx<T>(GGraph gp, Fx_Type fx_Type, ref Action Rec) where T : Component
        {
            var fx = GetFx<T>(fx_Type);
            if (fx != null)
            {
                var goWrapper = new GoWrapper(fx.gameObject);
                gp.SetNativeObject(goWrapper);
                fx.transform.localPosition = Vector3.zero;
                fx.transform.localScale = Vector3.one * 100;
                fx.transform.localEulerAngles = Vector3.zero;
                Rec += () =>
                {
                    goWrapper.wrapTarget = null;
                    gp.SetNativeObject(null);
                    RecFx(fx_Type, fx);
                };
            }

            return fx;
        }

        public GameObject SetFx(GGraph gp, Fx_Type fx_Type, ref Action Rec, bool supportStencil = false)
        {
            GameObject fx = GetFx<GameObject>(fx_Type);
            if (fx != null)
            {
                var goWrapper = new GoWrapper(fx.gameObject);
                gp.SetNativeObject(goWrapper);
                fx.transform.localPosition = Vector3.zero;
                fx.transform.localScale = Vector3.one * 100;
                fx.transform.localEulerAngles = Vector3.zero;
                Rec += () =>
                {
                    goWrapper.wrapTarget = null;
                    gp.SetNativeObject(null);
                    RecFx(fx_Type, fx);
                };
            }

            return fx;
        }
    }

    public enum Fx_Type
    {
        None = -1,
        gamwin,
        fx_broad,
        fx_login_light,
        fx_login_bird,
        fx_btn_play,
        fx_coin,
        fx_hand_pre,
        fx_disaappear_1,
        fx_disaappear_2,
        fx_first_reward,
        fx_egg,
        fx_egg_light,
        fx_gift_bg,
        fx_lock_light,
        fx_removeAD,
        fx_removeAD_bg,
        fx_saving,
        fx_sign1,
        fx_lock,
        fx_open,
        fx_lose,
        fx_three_gift,
        fx_tips,
        fx_wheel,
        fx_win,
        fx_winstar,
        fx_proplight,
        fx_addeffect,
        fx_addeffect_1,
        fx_free_idle = 104,
        fx_ui_jinbi_click = 107,
    }
}