using System.IO;

namespace Mafia2Tool.DataFormats.FrameResources
{
    public class SkeletonEntry : FrameResourceEntry
    {
        public class SkeletonLodInfo
        {
            public Bounds[] bounds;
            public byte[] IndexMap;
            public byte[] LodBlendIndexMap;

            public SkeletonLodInfo(BinaryReader r, SkeletonEntry p)
            {
                Read(r, p);
            }

            public void Read(BinaryReader r, SkeletonEntry p)
            {
                int count = p.count4;
                bounds = new Bounds[count];
                for (int i = 0; i < count; i++)
                {
                    bounds[i] = new Bounds(r);
                }
                
                IndexMap = r.ReadBytes(count);

                byte count2 = r.ReadByte();
                LodBlendIndexMap = r.ReadBytes(count2);
            }
        }

        public int count1; // name, matrices, bounds, ... ???
        public int count2;
        public int count3;
        public int count4;
        public int numBlendIndices; // TODO: numBlendindices

        byte LodFlag; // 0 = ?, 1 = lod0, 3 = lod0 | lod1, ... ?

        public Hash[] names;
        public TransformMatrix[] mats1; // ??? joint space, ???

        public byte[] LodFlags; // 0 = ?, 1 = lod0, 3 = lod0 | lod1, ... ?
        public TransformMatrix[] WorldTransforms; // ??? world space = extract position matrix, extract rotation matrix, multiply -position * rotation
        
        public SkeletonLodInfo[] lodInfo;

        public SkeletonEntry(BinaryReader r, FrameResourceEntryList list)
            : base(list)
        {
            Read(r);
        }

        public void Read(BinaryReader r)
        {
            count1 = r.ReadInt32();
            count2 = r.ReadInt32();
            count3 = r.ReadInt32();
            count4 = r.ReadInt32();
            System.Diagnostics.Debug.Assert(count1 == count2 && count2 == count3 && count3 == count4);

            numBlendIndices = r.ReadInt32();

            int count6 = r.ReadInt32();
            int[] counts7 = new int[count6];
            for (int i = 0; i < count6; i++) counts7[i] = r.ReadInt32();
            LodFlag = r.ReadByte();

            names = new Hash[count1];
            for (int i = 0; i < count1; i++)
            {
                names[i] = new Hash(r);
            }

            mats1 = new TransformMatrix[count2]; // or count2, count3, ...
            for (int i = 0; i < count2; i++)
            {
                mats1[i] = new TransformMatrix(r);
            }

            int count8 = r.ReadInt32();
            LodFlags = r.ReadBytes(count8);

            WorldTransforms = new TransformMatrix[count3]; // or count2, count3, ...
            for (int i = 0; i < count3; i++)
            {
                WorldTransforms[i] = new TransformMatrix(r);
            }

            lodInfo = new SkeletonLodInfo[count6];
            for (int i = 0; i < count6; i++)
            {
                lodInfo[i] = new SkeletonLodInfo(r, this);
            }
        }

        public override string ToString()
        {
            return string.Format("Skeleton ({0})", Index);
        }    
    }
}
