using System.Collections.Generic;
using BulletCLI;
//using BulletX.Dynamics;

namespace MikuMikuDance.XNA.Model
{
    /// <summary>
    /// 物理演算を扱うクラス
    /// model has a MMDPhysicsの関係
    /// </summary>
    class MMDPhysics
    {
        MMDBoneManager BoneManager;
        //MMDの剛体
        internal List<MMDPhysicsObject> Rigids { get; private set; }
        //MMDのジョイント
        internal List<MMDPhysicJoint> Joints { get; private set; }
        // コンストラクタ
        internal MMDPhysics(MMDModel model, DiscreteDynamicsWorld Physic)
        {
            //初期化
            Rigids = new List<MMDPhysicsObject>();
            Joints = new List<MMDPhysicJoint>();
            BoneManager = model.BoneManager;
            //剛体の作成
            for (int i = 0; i < model.ModelData.Rigids.Length; i++)
            {
                Rigids.Add(MMDPhysicsObject.PhisicsObjectFactory(model.ModelData.Rigids[i], model, Physic));
            }
            //ジョイント(拘束)の作成
            for (int i = 0; i < model.ModelData.Joints.Length; i++)
            {
                MMDPhysicsObject phisic0 = Rigids[(int)model.ModelData.Joints[i].RigidBodyA];
                MMDPhysicsObject phisic1 = Rigids[(int)model.ModelData.Joints[i].RigidBodyB];
                MMDPhysicJoint joint = new MMDPhysicJoint(phisic0.body, phisic1.body, model.ModelData.Joints[i], Physic);
                Joints.Add(joint);

            }
            //剛体を関連ボーン番号をもとにソート
            Rigids.Sort(new MMDPhisicsSorter());
            
        }
        internal void Update()
        {
            //剛体の運動差分→ボーンへの適応
            foreach (var i in Rigids)
            {
                i.ApplyRigitToBone();
            }
            //ボーンの運動→剛体への適応
            foreach (var i in Rigids)
            {
                i.ApplyBoneToRigit();
            }
        }
        /// <summary>
        /// 現在のボーンの位置に物理を合せる
        /// </summary>
        internal void ResetRigid(MMDModel model)
        {
            model.BoneManager.UpdateWorldTransforms();
            foreach (var i in Rigids)
            {
                i.ResetRigid();
            }
        }
    }
}
