using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using Microsoft.Xna.Framework.Graphics;
using MikuMikuDance.Motion.Motion2;
using MikuMikuDance.XNA.Motion.MotionData;
using TInput = MikuMikuDance.XNA.Motion.BakeMotionSet;
using TOutput = MikuMikuDance.XNA.Motion.MMDBakedMotion;
using MikuMikuDance.Model;
using MikuMikuDance.XNA.Model;
using MikuMikuDance.XNA.Model.ModelData;
using MikuMikuDance.Motion;

namespace MikuMikuDance.XNA.Motion
{
    /// <summary>
    /// ベイク済みモーション作成プロセッサ
    /// </summary>
    [ContentProcessor(DisplayName = "MikuMikuDanceモーションベイク : MikuMikuDance for XNA")]
    public class MMDBakedMotionProcessor : ContentProcessor<TInput, TOutput>
    {
        /// <summary>
        /// モーションのベイク処理
        /// </summary>
        /// <param name="input">ベイクモーションセット</param>
        /// <param name="context">ベイク済みモーション</param>
        /// <returns></returns>
        public override TOutput Process(TInput input, ContentProcessorContext context)
        {
            //モーションの変換
            string modelName = input.model.Name;
            MMDMotion2 motion2 = MotionManager.Read(input.motion.Filename, MikuMikuDance.Motion.CoordinateType.LeftHanded) as MMDMotion2;
            MMDModelIntermediate modelInter = context.BuildAndLoadAsset<MMDModelIntermediate, MMDModelIntermediate>(input.model, null);
            MMDMotionProcessor motionProc = new MMDMotionProcessor();
            MMDProcessor modelProc = new MMDProcessor();
            MMDMotionData motionData = motionProc.Process(motion2, context);
            MMDModelContext model = modelProc.Process(modelInter, context);
            //ベイクルーチンでベイクする
            int NumThread;
            //論理コア数を取得して、最適スレッド数を取得
            Win32API.SYSTEM_INFO info = new Win32API.SYSTEM_INFO();
            Win32API.GetSystemInfo(ref info);
            NumThread = (int)info.dwNumberOfProcessors;
            //MikuMikuDance for XNAのベイク機能を呼び出して、このタイミングでベイクを行う
            //この場にノーマルモーショントラックを生成する
            NormalMotionTrack normal = new NormalMotionTrack();
            MMDMotion motion = new MMDMotion();
            motion.Initialize(motionData);
            normal.Motion = motion;
            normal.IsEmpty = false;
            //MMDModelDataが要るのだが、モデルポリゴンデータが邪魔で作れないので、それ抜きで無理やり作る
            MMDModelData ModelData = new MMDModelData();
            ModelData.Bones = model.Bones;
            ModelData.Joints = model.Joints;
            ModelData.ModelData = null;//これだけは一度書き出さないと作れない……、ベイクには要らないので無視
            ModelData.NumVertexForFace = model.NumVertexForFace;
            ModelData.Rigids = model.Rigids;
            ModelData.Skins = model.Skins;
            //モデルデータより、ボーンマネージャとフェイスマネージャを生成する
            MMDBoneManager BoneManager = new MMDBoneManager(ModelData);
            MMDFaceManager FaceManager = new MMDFaceManager(ModelData);
            //MikuMikuDance for XNAのベイク機能を呼び出してベイク
            TOutput result = AnimationBaker.Bake(NumThread, normal, BoneManager, FaceManager);
            //モデル名格納
            result.ModelName = modelName;
            return result;
        }
    }
}