using System;
using System.Numerics;
using BepuPhysics;
using BepuPhysics.Collidables;

namespace Plugins.JNGame.BepuPhysics.Components
{
    public abstract class BPhysicsBase : UnityEngine.MonoBehaviour
    {

        //世界索引
        public int worldIndex = 0;
        
        protected BodyHandle BodyId;
        protected StaticHandle StaticBodyId;
        
        //是否静态
        public Boolean isStatic = false;

        public JNBepuPhysics Physics
        {
            get
            {
                JNBepuPhysics.Physics.TryGetValue(worldIndex, out var value);
                return value;
            }
        }

        protected void AddDynamic<TShape>(TShape shape,BodyInertia shapeInertia) where TShape : unmanaged, IShape
        {
            
            var sphereIndex = this.Physics.Simulation.Shapes.Add(shape);
            var transformPosition = transform.position;
            var transformRotation = transform.rotation;
            var spherePose = new RigidPose(new Vector3(transformPosition.x,transformPosition.y,transformPosition.z), new Quaternion(transformRotation.x,transformRotation.y,transformRotation.z,transformRotation.w));
            BodyId = this.Physics.Simulation.Bodies.Add(BodyDescription.CreateDynamic(spherePose,
                shapeInertia,
                new CollidableDescription(sphereIndex, 0.01f),
                new BodyActivityDescription(0.01f)));
            
        }

        protected void AddStatic<TShape>(TShape shape) where TShape : unmanaged, IShape
        {
            
            var transformPosition = transform.position;
            var transformRotation = transform.rotation;
            StaticBodyId = this.Physics.Simulation.Statics.Add(
                new StaticDescription(new Vector3(transformPosition.x, transformPosition.y, transformPosition.z),
                new Quaternion(transformRotation.x,transformRotation.y,transformRotation.z,transformRotation.w),
                new CollidableDescription(this.Physics.Simulation.Shapes.Add(shape), 0.01f)));
            
        }

        public void OnPhysicsUpdate(float dt)
        {
            
            if (this.Physics == null) return;
            if (this.isStatic) return;
            
            this.Physics.Simulation.Bodies.GetDescription(this.BodyId,out var info);

            //同步位置
            var transform1 = transform;
            transform1.position =
                new UnityEngine.Vector3(info.Pose.Position.X, info.Pose.Position.Y, info.Pose.Position.Z);
            //同步旋转
            transform1.rotation =
                new UnityEngine.Quaternion(info.Pose.Orientation.X, info.Pose.Orientation.Y, info.Pose.Position.Z,info.Pose.Orientation.W);

        }

    }
}