using System;
using System.Collections.Generic;
using System.ComponentModel;
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 TInput = Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent;
using TOutput = MikuMikuDance.XNA.Model.MMDModelContent;

namespace MikuMikuDance.XNA.Model
{
    /// <summary>
    /// MikuMikuDanceのモデルデータをXNAにインポートするためのプロセッサ(Reachバージョン)
    /// </summary>
    /// <remarks>Reachモデルはトゥーン無し、ボーン72個制限、シェーダ2.0対応となります</remarks>
    [ContentProcessor(DisplayName = "MikuMikuDance-HiDefモデル : MikuMikuDance for XNA")]
    public class MMDReachProcessor : ContentProcessor<TInput, TOutput>
    {
        bool generateMipmaps = true;
        /// <summary>
        /// ミップマップの生成
        /// </summary>
        [DefaultValue(true)]
        [DisplayName("ミップマップの生成")]
        [Description("有効な場合、モデルのテクスチャーに対して完全なミップマップ チェーンが生成されます。既存のミップマップは置換されません。")]
        public virtual bool GenerateMipmaps { get { return generateMipmaps; } set { generateMipmaps = value; } }

        bool resizeTexturesToPowerOfTwo = true;
        /// <summary>
        /// テクスチャサイズを2の累乗にリサイズ
        /// </summary>
        [DefaultValue(true)]
        [DisplayName("テクスチャー サイズを2の累乗にリサイズ")]
        [Description("有効な場合、モデルのテクスチャーは次に大きな2の累乗のサイズに変更され、可能な限りの互換性を保ちます。多くのグラフィック カードは、サイズが2の累乗でないテクスチャーに対応していません。")]
        public virtual bool ResizeTexturesToPowerOfTwo { get { return resizeTexturesToPowerOfTwo; } set { resizeTexturesToPowerOfTwo = value; } }

        TextureProcessorOutputFormat textureFormat = TextureProcessorOutputFormat.DxtCompressed;
        /// <summary>
        /// テクスチャーフォーマット
        /// </summary>
        [DefaultValue(TextureProcessorOutputFormat.DxtCompressed)]
        [DisplayName("テクスチャー フォーマット")]
        [Description("処理されるテクスチャーの SurfaceFormat 型を指定します。テクスチャーのフォーマットは、無変換、Color (32 ビット RGBA)、またはDXT圧縮形式に変換されます。")]
        public virtual TextureProcessorOutputFormat TextureFormat { get { return textureFormat; } set { textureFormat = value; } }

        bool m_UsePartCenterZSort = false;
        /// <summary>
        /// パーツ中心を利用したモデル内Zソート法
        /// </summary>
        [DefaultValue(false)]
        [DisplayName("パーツ中心Zソート法")]
        [Description("有効な場合、モデルの各材質は各材質の中心位置を基準としたZソート法で描画されます。半透明材質やテクスチャを持つモデルが上手く表示されないときにtrueにすると解決するかもしれません")]
        public bool UsePartCenterZSort { get { return m_UsePartCenterZSort; } set { m_UsePartCenterZSort = value; } }

        /// <summary>
        /// コンテンツをMMD-Reach仕様に変換
        /// </summary>
        /// <param name="input">モデル</param>
        /// <param name="context">コンテントプロセッサ</param>
        /// <returns>MMDモデル(Reach) for XNAコンテンツ</returns>
        public override TOutput Process(TInput input, ContentProcessorContext context)
        {

            //モデルの中間ビルドタグをチェックし、インポータがMMDImporterかそれ以外かを判別
            MMDModelIntermediateTag intertag = null;
            object data;
            if (input.OpaqueData.TryGetValue("mmdtag", out data))
            {//符号タグチェック

                intertag = data as MMDModelIntermediateTag;
            }
            if (intertag != null)
            {//MMDImporterからのモデル
                input.OpaqueData.Remove("mmdtag");
                //情報をPMD→Reachプロセッサにかける
                InnerProcessorPMDReach.GenerateMipmaps = GenerateMipmaps;
                InnerProcessorPMDReach.ResizeTexturesToPowerOfTwo = ResizeTexturesToPowerOfTwo;
                InnerProcessorPMDReach.TextureFormat = TextureFormat;
                InnerProcessorPMDReach.UsePartCenterZSort = UsePartCenterZSort;
                return InnerProcessorPMDReach.Process(input, intertag, context);
            }
            else
            {
                //通常のインポータからのモデル
                throw new NotImplementedException();
            }
            
        }
    }
}