using System;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using MikuMikuDance.XNA.Motion;
using MikuMikuDance.XNA.Accessory;
namespace MikuMikuDance.XNA.Model
{
    /// <summary>
    /// MMDModelインターフェイス
    /// </summary>
    public interface MMDModel
    {
        /// <summary>
        /// モデル名
        /// </summary>
        string Name { get; }
        /// <summary>
        /// MikuMikuDanceXNA.TimeRularをこのモデルが呼び出すかどうか
        /// </summary>
        bool UseTimeRular { get; set; }
        /// <summary>
        /// Draw を呼び出す必要があるかどうかを示します。
        /// </summary>
        bool Visible { get; set; }
        /// <summary>
        /// ボーンマネージャ
        /// </summary>
        MMDBoneManager BoneManager { get; }
        /// <summary>
        /// フェイスマネージャ
        /// </summary>
        MMDFaceManager FaceManager { get; }
        /// <summary>
        /// アニメーションプレイヤー
        /// </summary>
        AnimationPlayer Player { get; }
        /// <summary>
        /// 物理マネージャー
        /// </summary>
        MMDPhysicsManager Physics { get; }
        
        /// <summary>
        /// モーションを適用する直前に呼ばれる
        /// </summary>
        event UpdateDelegate BeforeApplyMotion;
        /// <summary>
        /// モーションを適応した直後、MMDBoneManager.Update()(MMDBone.WorldTransformを計算する関数)が呼ばれるまでの間に呼ばれる
        /// </summary>
        /// <remarks>モーションをプログラムから操作したい場合はこのイベントを利用する</remarks>
        event UpdateDelegate AfterApplyMotion;
        /// <summary>
        /// MMDBoneManager.Update()を行った直後に呼ばれる
        /// </summary>
        /// <remarks>このタイミングでボーンのWorldTransformの更新まで終わっている</remarks>
        event UpdateDelegate AfterBoneManagerUpdate;

        /// <summary>
        /// アクセサリをモデルに関連付け
        /// </summary>
        /// <param name="accessory">アクセサリ</param>
        /// <param name="vacData">VAC設定データ</param>
        void SetAccessory(MMDAccessory accessory, MMD_VAC vacData);
        /// <summary>
        /// アクセサリをモデルに関連付け
        /// </summary>
        /// <param name="accessory">アクセサリ</param>
        /// <param name="transform">アクセサリの位置</param>
        /// <param name="boneName">基準ボーン名</param>
        void SetAccessory(MMDAccessory accessory, Matrix transform, string boneName);
        /// <summary>
        /// アクセサリのモデルへの関連付けの解除
        /// </summary>
        /// <param name="accessory">アクセサリ</param>
        void ReleaseAccessory(MMDAccessory accessory);
    }
}
