using System.Collections.Generic;
using FairyGUI;

namespace ChillConnect
{
    public abstract class BaseUI
    {
        protected UIManager mUIManager;
        protected ModuleManager moduleManager;

        protected ModelDispatcher modelDispatcher;
        protected CtrlDispatcher ctrlDispatcher;
        protected UICtrlDispatcher uiCtrlDispatcher;
        protected DataDispatcher dataDispatcher;
        protected GameDispatcher gameDispatcher;

        public string uiName;
        public string rawGameObjectName;
        public string gameObjectName;
        public UIInfo uiInfo;

        public uint uiOpenCumsumId;
        public int currLayer;
        public BaseUICtrl baseUICtrl;
        public object uiArgs;

        public GObject baseGObj;
        public GComponent baseUI;
        public Window windowUI;
        public GGraph uiMask;
        public List<SubUI> subUIs;

        public bool isOpen;
        public bool isVisible;
        public bool isClose;

        public GTweener openUiGTweener;
        public GTweener closeUiGTweener;

        public BaseUI(BaseUICtrl baseUICtrl)
        {
            New(baseUICtrl);
        }

        public void New(BaseUICtrl baseUICtrl)
        {
            this.baseUICtrl = baseUICtrl;

            Assignment();
            OnNew();
            Process_Init();
        }

        protected virtual void Assignment()
        {
            mUIManager = UIManager.Instance;
            moduleManager = ModuleManager.Instance;

            modelDispatcher = ModelDispatcher.Instance;
            ctrlDispatcher = CtrlDispatcher.Instance;
            uiCtrlDispatcher = UICtrlDispatcher.Instance;
            dataDispatcher = DataDispatcher.Instance;
            gameDispatcher = GameDispatcher.Instance;
        }

        protected virtual void UnAssignment()
        {
            mUIManager = null;
            moduleManager = null;

            modelDispatcher = null;
            ctrlDispatcher = null;
            uiCtrlDispatcher = null;
            dataDispatcher = null;
            gameDispatcher = null;
        }


        public void Open(object args = null)
        {
            uiArgs = args;
            mUIManager.Internal_OpenUI(this, args);
        }

        public void Close()
        {
            if (isClose) return;
            mUIManager.Internal_CloseUI(this);
        }

        public void Hide()
        {
            mUIManager.Internal_HideUI(this);
        }

        public void Display(object args = null)
        {
            uiArgs = args;
            mUIManager.Internal_DisplayUI(this, args);
        }


        private void Process_Init()
        {
            isOpen = false;
            isVisible = false;
            isClose = false;

            uiInfo = new UIInfo();

            SetUIInfo(uiInfo);
            PostProcess_UIInfo();
            OnInit();
        }

        private void PostProcess_UIInfo()
        {
        }

        public void Process_Bind()
        {
            OnBind();
        }

        public void Process_OpenBefore(object args)
        {
            OnOpenBefore(args);
        }

        public void Process_Open(object args)
        {
            OnOpen(args);
            AddListener();
            AddServerListener();

            isOpen = true;
        }

        public void Process_OpenUIAnimEnd()
        {
            OnOpenUIAnimEnd();
        }

        public void Process_Close()
        {
            RemoveListener();
            RemoveServerListener();
            OnClose();

            isClose = true;
        }

        public void Process_CloseUIAnimEnd()
        {
            OnCloseUIAnimEnd();
        }

        public void Process_Destroy()
        {
            OnDestroy();
            UnAssignment();

            isOpen = false;
            isVisible = false;
            isClose = true;

            baseGObj = null;
            baseUI = null;
            windowUI = null;
        }

        public void Process_Hide()
        {
            isVisible = false;
            baseUI.visible = isVisible;
            OnHide();
        }

        public void Process_Display(object args)
        {
            isVisible = true;
            baseUI.visible = isVisible;
            OnDisplay(args);
        }

        public void ProcessFunc_SwitchLanguage()
        {
            if (isClose) return;
            if (baseUI == null) return;
            if (baseUI.isDisposed) return;

            InternaProcesslFunc_GComponentSwitchLanguage(baseUI);
            OnSwitchLanguage();
        }

        private void InternaProcesslFunc_GComponentSwitchLanguage(GComponent switchCom)
        {
            if (switchCom == null) return;
            if (switchCom.isDisposed) return;

            for (int i = 0; i < switchCom.GetChildrenCount(); i++)
            {
                GObject gObject = switchCom.GetChildAt(i);
                if (gObject == null || gObject.isDisposed) continue;

                GComponent childCom = gObject.asCom;
                if (childCom != null)
                {
                    InternaProcesslFunc_GComponentSwitchLanguage(childCom);
                    continue;
                }

                if (gObject.packageItem != null) continue;
                if (gObject.parent == null) continue;

                string text = null;
                if (gObject is GTextField)
                {
                    GTextField gTextField = gObject.asTextField;
                    if (gTextField == null) continue;
                    if (!gTextField.Ex_IsAutoMultiLang) continue;

                    text = gObject.Ex_GetMultiLangText();
                    if (text != null)
                    {
                        gTextField.text = text;
                    }
                }
            }
        }

        protected virtual void OnNew()
        {
        }

        protected abstract void SetUIInfo(UIInfo uiInfo);

        protected virtual void OnInit()
        {
        }

        protected virtual void OnBind()
        {
        }

        protected virtual void OnOpenBefore(object args)
        {
        }

        protected virtual void OnOpen(object args)
        {
        }

        protected virtual void OnOpenUIAnimEnd()
        {
        }

        protected virtual void OnClose()
        {
        }

        protected virtual void OnCloseUIAnimEnd()
        {
        }

        protected virtual void OnDestroy()
        {
        }

        protected virtual void OnHide()
        {
        }

        protected virtual void OnDisplay(object args)
        {
        }

        public virtual void OnUpdate()
        {
        }

        public virtual void OnSwitchLanguage()
        {
        }

        protected virtual void AddListener()
        {
        }

        protected virtual void RemoveListener()
        {
        }

        protected virtual void AddServerListener()
        {
        }

        protected virtual void RemoveServerListener()
        {
        }

        public void KillOpenUIAnim()
        {
            if (openUiGTweener != null)
            {
                if (!openUiGTweener.allCompleted)
                {
                    openUiGTweener.Kill(complete: false);
                }

                openUiGTweener = null;
            }
        }

        public void KillCloseUIAnim()
        {
            if (closeUiGTweener != null)
            {
                if (!closeUiGTweener.allCompleted)
                {
                    closeUiGTweener.Kill(complete: false);
                }

                closeUiGTweener = null;
            }
        }

        public void CtrlCloseUI()
        {
            if (baseUICtrl == null) return;

            baseUICtrl.DispatchCloseUI(uiName);
        }
    }
}