using System.Collections;
using System.Collections.Generic;
using MyFrameworkPure;
using UnityEngine;
#if STEAMVR
using HTC.UnityPlugin.Vive;
#endif
namespace CommonScript
{
    public enum MouseButton
    {
        Left = 0,
        Right,
        Middle,
    }
    /// 
    /// 相机旋转的通用脚本
    /// 
    public class CameraRotator : MonoBehaviour
    {
        [Header("鼠标输入")]
        [SerializeField] private bool enableMouseInput = true;
        [SerializeField] private MouseButton mouseButton = MouseButton.Left;
        [SerializeField] private float mouseRotSpeed = 5;
        [Header("触屏输入")]
        [SerializeField] private bool enableTouchInput = true;
#if STEAMVR
        [Header("Vive输入")]
        [SerializeField] private bool enableViveInput = true;
        [SerializeField] private ViveRoleProperty viveRoleProperty = ViveRoleProperty.New(HandRole.RightHand);
        [SerializeField] private float viveRotSpeed = 30;
#endif
        [Header("其他参数")]
        [SerializeField] private Transform cameraTransform;
        [SerializeField] private Transform target;
        [SerializeField] private bool lookatTarget = true;
        [SerializeField] private bool allowZoom = true;
        [SerializeField] private float zoomSpeed = 50;
        [SerializeField] private float farestToTarget = 3000f;
        [SerializeField] private float nearestToTarget = 0f;
        [SerializeField] private bool clampEuler = true;
        [SerializeField] private float minEulerX = 0;
        [SerializeField] private float maxEulerX = 180;
        [SerializeField] private float minEulerY = -180;
        [SerializeField] private float maxEulerY = 180;
        public Transform target_yinyong;
        private Vector3 lastMousePos;
        private Vector2 lastTouchPos;
        private Vector3 lastCameraPos;
        private Vector3 lastCameraRot;
        // Start is called before the first frame update
        void Start()
        {
            cameraTransform = cameraTransform != null?cameraTransform:transform;
            SetTarget(target);
        }
        // Update is called once per frame
        void Update()
        {
            if (enableMouseInput)
                HandleMouseInput();
            if (enableTouchInput)
                HandleTouchInput();
            //if (enableViveInput)
            //    HandleViveInput();
            if (clampEuler)
                ClampEuler();
            if (lookatTarget && target)
            {
                cameraTransform.LookAt(target);
            }
            if (allowZoom && target)
            {
                ClameDistanceToTarget();
            }
            RecordCameraTransform();
        }
        public void SetTarget(Transform target)
        {
            //校验目标物合法性
            if (target)
            {
                float distance = Vector3.Distance(cameraTransform.position, target.position);
                if (allowZoom && (distance > farestToTarget || distance < nearestToTarget))
                {
                    Debug.LogError("相机初始位置不满足要求!");
                    return;
                }
                Vector3 euler = VectorTool.ConvertToEuler180(cameraTransform.eulerAngles);
                if (clampEuler && (euler.x < minEulerX || euler.x > maxEulerX))
                {
                    Debug.LogError("相机旋转X分量不满足要求");
                    return;
                }
                if (clampEuler && (euler.y < minEulerY || euler.y > maxEulerY))
                {
                    Debug.LogError("相机旋转Y分量不满足要求");
                    return;
                }
            }
            else
            {
                if (allowZoom || lookatTarget)
                {
                    Debug.LogError("开启相机缩放或朝向目标开关,要求目标物不能为空!");
                    return;
                }
            }
            this.target = target;
            RecordCameraTransform();
            target_yinyong = target;
        }
        void HandleMouseInput()
        {
            if (Input.GetMouseButtonDown((int)mouseButton))
            {
                lastMousePos = Input.mousePosition;
            }
            if (Input.GetMouseButton((int)mouseButton))
            {
                Vector3 delta = Input.mousePosition - lastMousePos;
                if (target)
                {
                    cameraTransform.RotateAround(target.position,-cameraTransform.right, delta.y * mouseRotSpeed * Time.deltaTime);
                    ClampPosFromEulerX();
                    cameraTransform.RotateAround(target.position,Vector3.up,delta.x * mouseRotSpeed * Time.deltaTime);
                    ClampPosFromEulerY();
                }
                else
                {
                    cameraTransform.Rotate(Vector3.left * delta.y * mouseRotSpeed * Time.deltaTime, Space.Self);
                    cameraTransform.Rotate(Vector3.up * delta.x * mouseRotSpeed * Time.deltaTime, Space.World);
                }
                lastMousePos = Input.mousePosition;
            }
            if (allowZoom)
            {
                float mouseScroll = Input.GetAxis("Mouse ScrollWheel");
                cameraTransform.Translate(Vector3.forward * mouseScroll * zoomSpeed * Time.deltaTime);
            }
        }
        void HandleTouchInput()
        {
            if(Input.touchCount == 0)
                return;
            Touch touch = Input.GetTouch(0);
            if (touch.phase == TouchPhase.Began)
            {
                lastTouchPos = touch.position;
            }
            else if(touch.phase == TouchPhase.Moved)
            {
                Vector3 delta = touch.position - lastTouchPos;
                if (target)
                {
                    cameraTransform.RotateAround(target.position, -cameraTransform.right, delta.y * mouseRotSpeed * Time.deltaTime);
                    ClampPosFromEulerX();
                    cameraTransform.RotateAround(target.position, Vector3.up, delta.x * mouseRotSpeed * Time.deltaTime);
                    ClampPosFromEulerY();
                }
                else
                {
                    cameraTransform.Rotate(Vector3.left * delta.y * mouseRotSpeed * Time.deltaTime, Space.Self);
                    cameraTransform.Rotate(Vector3.up * delta.x * mouseRotSpeed * Time.deltaTime, Space.World);
                }
                
                lastTouchPos = touch.position;
            }
        }
        void HandleViveInput()
        {
#if STEAMVR
            Vector2 pressPos = HTC.UnityPlugin.Vive.ViveInput.GetPadPressAxis(viveRoleProperty);
            if(Vector2.Distance(Vector2.zero,pressPos) < 0.01f)
                return;
            //将触摸板位置划分上下左右四块区域
            float angle = Vector2.SignedAngle(Vector2.right, pressPos);
            if (angle > -45 && angle <= 45)
            {
                pressPos = Vector2.right;
            }
            else if(angle > 45 && angle <=135)
            {
                pressPos = Vector2.up;
            }
            else if(angle > 135 || angle < -135)
            {
                pressPos = Vector2.left;
            }
            else 
            {
                pressPos = Vector2.down;
            }
            if (target)
            {
                cameraTransform.RotateAround(target.position, -cameraTransform.right, pressPos.y * viveRotSpeed * Time.deltaTime);
                ClampPosFromEulerX();
                cameraTransform.RotateAround(target.position, Vector3.up, pressPos.x * viveRotSpeed * Time.deltaTime);
                ClampPosFromEulerY();
            }
            else
            {
                cameraTransform.Rotate(Vector3.left * pressPos.y * viveRotSpeed * Time.deltaTime, Space.Self);
                cameraTransform.Rotate(Vector3.up * pressPos.x * viveRotSpeed * Time.deltaTime, Space.World);
            }
#endif
        }
        /// 
        /// 限制相机旋转角度
        /// 
        void ClampEuler()
        {
            Vector3 euler = VectorTool.ConvertToEuler180(cameraTransform.eulerAngles);
            euler = new Vector3(Mathf.Clamp(euler.x,minEulerX,maxEulerX),Mathf.Clamp(euler.y,minEulerY,maxEulerY),0);
            cameraTransform.eulerAngles = euler;
        }
        void ClampPosFromEulerX()
        {
            Vector3 euler = VectorTool.ConvertToEuler180(cameraTransform.eulerAngles);
            if (euler.x < minEulerX || euler.x > maxEulerX)
            {
                RestoreCameraTransform();
            }
        }
        void ClampPosFromEulerY()
        {
            Vector3 euler = VectorTool.ConvertToEuler180(cameraTransform.eulerAngles);
            if (euler.y < minEulerY || euler.y > maxEulerY)
            {
                RestoreCameraTransform();
            }
        }
        /// 
        /// 限制相机到目标的距离
        /// 
        void ClameDistanceToTarget()
        {
            float distance = Vector3.Distance(cameraTransform.position, target.position);
            if (distance < nearestToTarget || distance > farestToTarget)
            {
                RestoreCameraTransform();
            }
        }
        /// 
        /// 记录相机的变换信息
        /// 
        void RecordCameraTransform()
        {
            lastCameraPos = cameraTransform.transform.position;
            lastCameraRot = cameraTransform.transform.eulerAngles;
        }
        /// 
        /// 恢复相机变换到上一帧
        /// 
        void RestoreCameraTransform()
        {
            cameraTransform.position = lastCameraPos;
            cameraTransform.eulerAngles = lastCameraRot;
        }
    }
}