using FairyGUI;
using UnityEngine;
using UnityEngine.EventSystems;

namespace ChillConnect
{
    public sealed class CameraManager : BaseInterfaceManager<CameraManager>
    {
        public Transform mainCameraRoot;
        public GameObject mainCameraGo;
        public Camera mainCamera;

        public Transform fguiCameraRoot;
        public GameObject fguiCameraGo;
        public Camera fguiCamera;


        public bool isEnabledWorldRaycast;
        public Physics2DRaycaster physics2DRaycaster;
        public PhysicsRaycaster physics3DRaycaster;

        private bool isMainCameraShakeing;

        #region Coordinate

        public Vector2 WorldPosToFGUIPos(Vector3 worldPos)
        {
            Vector3 screenPos = mainCamera.WorldToScreenPoint(worldPos);

            screenPos.y = ScreenConst.CurrResolution.y - screenPos.y;
            Vector2 pt = GRoot.inst.GlobalToLocal(screenPos);
            return pt;
        }

        #endregion

        #region Func

        public void SetWorldRaycasterEnabled(bool enabled)
        {
            isEnabledWorldRaycast = enabled;
            if (physics2DRaycaster != null)
            {
                EventKit.Set2DRaycasterEnabled(physics2DRaycaster, isEnabledWorldRaycast);
            }

            if (physics3DRaycaster != null)
            {
                EventKit.Set3DRaycasterEnabled(physics3DRaycaster, isEnabledWorldRaycast);
            }

            AppDispatcher.Instance.Dispatch(AppMsg.WorldRaycast_EnableChange, isEnabledWorldRaycast);
        }

        #endregion

        #region Camera

        public void CreateMainCamera()
        {
            if (mainCamera) return;

            string name = "MainCamera";
            mainCameraGo = new GameObject(name);
            mainCameraGo.tag = name;
            mainCameraGo.layer = LayerMaskConst.Default;
            mainCameraGo.transform.localPosition = Vector3.zero;
            int cullingMask = LayerMask.GetMask(LayerMaskConst.Default_Name);
            mainCamera = CreateCamera(mainCameraGo, cullingMask: cullingMask);
            mainCamera.clearFlags = CameraClearFlags.SolidColor;

            mainCamera.forceIntoRenderTexture = false;

            GameObject root = new GameObject(name + "Root");
            root.transform.position = CameraConst.MainCameraPos;
            root.SetParent(AppObjConst.CameraGo);
            mainCameraGo.SetParent(root);
            mainCameraRoot = root.transform;

            CameraAdaptive adaptiveCom = mainCamera.gameObject.AddComponent<CameraAdaptive>();
            adaptiveCom.DoAdaptive(isOrthographic: true, orthographicSize: ScreenConst.OrthographicSize_1280H);
        }

        public void CreateFGUICamera()
        {
            if (fguiCamera) return;

            StageCamera.CheckMainCamera();
            fguiCamera = StageCamera.main;
            fguiCamera.depth = CameraConst.UICameraDepth;

            fguiCamera.forceIntoRenderTexture = false;
            fguiCameraGo = fguiCamera.gameObject;

            GameObject root = new GameObject("FGUICameraRoot");
            root.transform.position = CameraConst.UICameraPos;
            root.SetParent(AppObjConst.CameraGo);
            fguiCameraGo.SetParent(root);
            fguiCameraRoot = root.transform;
        }

        public Camera CreateCamera(GameObject cameraGo, int cullingMask)
        {
            Camera cameraCom = cameraGo.AddComponent<Camera>();
            cameraCom.clearFlags = CameraClearFlags.Depth;
            cameraCom.backgroundColor = Color.black;
            cameraCom.cullingMask = cullingMask;
            cameraCom.nearClipPlane = -30f;
            cameraCom.farClipPlane = 30f;
            cameraCom.rect = new Rect(0, 0, 1f, 1f);
            cameraCom.depth = CameraConst.MainDepth;
            cameraCom.renderingPath = RenderingPath.UsePlayerSettings;
            cameraCom.useOcclusionCulling = false;
            cameraCom.allowHDR = false;
            cameraCom.allowMSAA = false;
            cameraCom.orthographicSize = 9.6f;
            cameraCom.forceIntoRenderTexture = false;
            return cameraCom;
        }

        #endregion

        #region Mgr

        public override void Init()
        {
            base.Init();
            InitCameraMgr();

            CreateMainCamera();
            CreateFGUICamera();
        }

        private void InitCameraMgr()
        {
            AppObjConst.CameraGo = new GameObject(AppObjConst.CameraGoName);
            AppObjConst.CameraGo.SetParent(AppObjConst.FrameGo);
        }

        public override void Dispose()
        {
            base.Dispose();
            GeneralKit.Destroy(AppObjConst.CameraGo);
        }

        #endregion
    }
}