using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mafia2Tool.DataFormats.FrameResources;

namespace Mafia2Tool.Parsed
{
    public class Skeleton : IList<SkeletonJoint>
    {
        private List<SkeletonJoint> _joints;

        public Skeleton(ModelComponent m, int lodIndex)
        {
            Build(m, lodIndex);
        }

        public void Build(ModelComponent m, int lodIndex)
        {
            var lodInfo = m.Skeleton.lodInfo[lodIndex];

            byte[] lodBlendIndices = lodInfo.LodBlendIndexMap;
            byte[] blendindices = new byte[lodInfo.LodBlendIndexMap.Length];

            int start = 0;
            foreach (var l in m.BlendInfo.BlendDataToBoneIndexMaps[lodIndex].BlendIndices)
            {
                Array.Copy(l, 0, blendindices, start, l.Length);
                start += l.Length;
            }

            _joints = new List<SkeletonJoint>();
            for (int i = 0; i < lodInfo.IndexMap.Length; i++)
            {
                if (lodInfo.IndexMap[i] < lodBlendIndices.Length)
                {
                    SkeletonJoint b = new SkeletonJoint(
                        lodIndex,
                        i,
                        (sbyte)m.SkeletonHierachy.ParentIndices[i],
                        this,
                        m.Skeleton.names[i],
                        m.Skeleton.LodFlags[i],
                        lodInfo.bounds[i],
                        m.Skeleton.WorldTransforms[i],
                        m.Skeleton.mats1[i]
                    );
                    _joints.Add(b);
                }
            }

            for (int i = 0; i < lodBlendIndices.Length; i++)
            {
                int jointIndex = blendindices[lodBlendIndices[i]];
                _joints[jointIndex].AffectedBlendIndices.Add(lodBlendIndices[i]);
            }
        }

        public List<int> GetAffectedJoints(int index)
        {
            List<int> tmp = new List<int>();
            tmp.Add(index);
            foreach (var j in _joints)
            {
                if (j.IsAffectedJoint(index))
                {
                    tmp.Add(j.Index);
                }
            }
            return tmp;
        }

        #region IList implementation
        public void Add(SkeletonJoint item)
        {
            throw new NotImplementedException();
        }

        public void Clear()
        {
            throw new NotImplementedException();
        }

        public bool Contains(SkeletonJoint item)
        {
            throw new NotImplementedException();
        }

        public void CopyTo(SkeletonJoint[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public int Count
        {
            get {
                if (_joints != null) return _joints.Count;
                return 0;
            }
        }

        public bool IsReadOnly
        {
            get { return true; }
        }

        public bool Remove(SkeletonJoint item)
        {
            throw new NotImplementedException();
        }

        public IEnumerator<SkeletonJoint> GetEnumerator()
        {
            return _joints.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _joints.GetEnumerator();
        }

        public int IndexOf(SkeletonJoint item)
        {
            if (_joints == null) return -1;
            return _joints.IndexOf(item);
        }

        public void Insert(int index, SkeletonJoint item)
        {
            throw new NotImplementedException();
        }

        public void RemoveAt(int index)
        {
            throw new NotImplementedException();
        }

        public SkeletonJoint this[int index]
        {
            get
            {
                if (_joints == null) return null;
                if (index >= 0 && index < _joints.Count) return _joints[index];
                return null;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        #endregion
    }
}
