using System;
using System.Diagnostics;
using BulletX.BulletCollision.CollisionDispatch;
using BulletX.LinerMath;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace BulletX
{
    //メモ
    //現在、マルチスレッドで動かすと、デバッグ用のワイヤーフレーム描画と本体の計算エンジンとで競合を起こす
    //競合箇所は剛体の情報をデバッグ用に取得する箇所と、計算結果を剛体に書き戻す処理
    //現在のところ、デバッグ時にのみ起こる問題かつあまり競合せず、競合しても問題は無い……
    public class DefaultDebugDraw : IDebugDraw
    {
        BasicEffect effect;
        VertexDeclaration vertexDec;
        CollisionWorld m_world;
        VertexPositionColor[] vertex;
        int VertCount = 0;
        DebugDrawModes mode;
        public override DebugDrawModes DebugMode
        {
            get { return mode; }
            set { mode = value; }
        }
        public void setDebugMode(DebugDrawModes newmode){mode=newmode;}

        public Matrix View;
        public Matrix Proj;

        public DefaultDebugDraw(GraphicsDevice device, CollisionWorld world)
        {
            world.DebugDrawer = this;
            m_world = world;
            effect = new BasicEffect(device, null);
            effect.VertexColorEnabled = true;
            effect.World = Matrix.Identity;
            vertexDec = new VertexDeclaration(device, VertexPositionColor.VertexElements);
            vertex = new VertexPositionColor[50];
            setDebugMode(DebugDrawModes.DBG_DrawWireframe | DebugDrawModes.DBG_DrawConstraints);
        }
        
        public virtual void Draw(GraphicsDevice graphics)
        {
            VertCount = 0;
            Array.Clear(vertex, 0, vertex.Length);
            m_world.debugDrawWorld();
            if (VertCount == 0)
                return;
            graphics.RenderState.AlphaBlendEnable = false;
            graphics.RenderState.AlphaTestEnable = true;
            graphics.RenderState.ReferenceAlpha = 1;
            graphics.RenderState.AlphaFunction = CompareFunction.GreaterEqual;
            graphics.RenderState.DepthBufferEnable = true;
            graphics.VertexDeclaration = vertexDec;
            effect.View = View;
            effect.Projection = Proj;
            effect.Begin();
            for (int i = 0; i < effect.CurrentTechnique.Passes.Count; i++)
            {
                var pass = effect.CurrentTechnique.Passes[i];
                pass.Begin();
                graphics.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, vertex, 0, VertCount);
                pass.End();
            }
            effect.End();
        }

        
            
        public override void drawLine(ref btVector3 from,ref btVector3 to,ref btVector3 color)
        {
            if (vertex.Length <= VertCount * 2)
            {
                Array.Resize(ref vertex, VertCount * 4);
            }
            vertex[VertCount * 2] = new VertexPositionColor(from.CreateXNAVector(), new Color(color.CreateXNAVector()));
            vertex[VertCount * 2 + 1] = new VertexPositionColor(to.CreateXNAVector(), new Color(color.CreateXNAVector()));
            VertCount++;
        }

        public override void drawContactPoint(ref btVector3 PointOnB,ref btVector3 normalOnB, float distance, int lifeTime,ref btVector3 color)
        {
            throw new NotImplementedException();
        }

        public override void reportErrorWarning(string warningString)
        {
            Debug.WriteLine(warningString);
        }

        public override void draw3dText(ref btVector3 location, string textString)
        {
            throw new NotImplementedException();
        }

        
    }
}
