using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using MikuMikuDance.XNA.Model.ModelData;

namespace MikuMikuDance.XNA.Model
{
    /// <summary>
    /// フェイスマネージャクラス
    /// </summary>
    public class MMDFaceManager
    {
        MMDModelData modelData;
        internal Vector4[] FaceRates;//GPU表情アニメーション用
        internal Vector4[] FaceVerts;//CPU表情アニメーション用
        //internal Dictionary<string, float> FaceRates;//適応中の表情リスト
        Dictionary<string, int> FaceDictionary;//表情辞書
        Dictionary<string, int> FaceRateDictionary;//表情レート用辞書
        Dictionary<int, int> RateToIndexDictionary;//表情レート→表情番号用辞書
        int baseIndex;

        internal MMDFaceManager CloneForBake()
        {
            return new MMDFaceManager(modelData);
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="mmdmodel">モデルデータ</param>
        public MMDFaceManager(MMDModelData mmdmodel)
        {
            modelData = mmdmodel;
            if (mmdmodel.IsReach)
                FaceVerts = new Vector4[0];
            else
                FaceVerts = new Vector4[mmdmodel.FaceVertTextureSizeX * mmdmodel.FaceVertTextureSizeY];
            //表情辞書を作っておく
            FaceDictionary = new Dictionary<string, int>();
            FaceRateDictionary = new Dictionary<string, int>();
            RateToIndexDictionary = new Dictionary<int, int>();
            baseIndex = 0;
            if (mmdmodel.IsReach)
            {
                FaceRates = new Vector4[0];
            }
            else
            {
                for (int i = 0; i < modelData.Skins.Length; i++)
                {
                    if (modelData.Skins[i].SkinType == 0)
                        baseIndex = i;
                    else
                        FaceDictionary.Add(modelData.Skins[i].Name, i);
                }
                int counter = 0;
                for (int i = 0; i < modelData.Skins.Length; i++)
                {
                    if (modelData.Skins[i].SkinType != 0)
                    {
                        FaceRateDictionary.Add(modelData.Skins[i].Name, counter);
                        RateToIndexDictionary.Add(counter, i);
                        counter++;
                    }
                }
                FaceRates = new Vector4[FaceRateDictionary.Count];
                Array.Clear(FaceRates, 0, FaceRates.Length);
            }
        }
        
        internal void UpdateRate(Dictionary<string, float> FaceRates)
        {
            //表情の適応量を設定
            foreach (var face in FaceRates)
            {//各表情ごとに適応量をセット
                this.FaceRates[FaceRateDictionary[face.Key]].X = face.Value;
            }
        }
        internal void CalcVertMove()
        {
            Array.Clear(FaceVerts, 0, FaceVerts.Length);
            for (int i = 0; i < FaceRates.Length; i++)
            {
                foreach(var v in modelData.Skins[RateToIndexDictionary[i]].SkinVerts)
                {
                    FaceVerts[v.VertIndex] += new Vector4(MMDMath.VectorFromArray(v.Pos) * FaceRates[i].X, 0);
                }
            }
        }

        internal bool ContainsFace(string p)
        {
            return FaceDictionary.ContainsKey(p);
        }


        internal Dictionary<string, List<uint>> GetVertIndices()
        {
            Dictionary<string, List<uint>> result = new Dictionary<string, List<uint>>();
            foreach (var fd in FaceDictionary)
            {
                List<uint> verts = new List<uint>();
                foreach (var vert in modelData.Skins[fd.Value].SkinVerts)
                {
                    verts.Add(vert.VertIndex);
                }
                result.Add(fd.Key, verts);
            }
            return result;
        }

        
    }
}
