/// <summary>
        /// Read the Texture MCNK from the texture ADT.
        /// </summary>
        public static void ReadTexMCNK(BinaryReader reader, uint mcnkSize, ADTModel model)
        {
            var startPosition = reader.BaseStream.Position;
            var texMcnk       = new TexMCNKChunk();

            while (reader.BaseStream.Position < startPosition + mcnkSize)
            {
                var chunkId   = (Chunks)reader.ReadUInt32();
                var chunkSize = reader.ReadUInt32();

                switch (chunkId)
                {
                case Chunks.MCLY:           // Texture Layers.
                    ReadMCLY(reader, chunkSize, texMcnk);
                    break;

                case Chunks.MCAL:           // Alpha Layers.
                    ReadMCAL(reader, texMcnk, model.WdtFileDataId, chunkSize);
                    break;

                default:
                    reader.Skip(chunkSize);
                    break;
                }
            }

            model.TexMCNKs.Add(texMcnk);
        }
        /// <summary>
        /// Read texture data from MCLY.
        /// </summary>
        public static void ReadMCLY(BinaryReader reader, uint chunkSize, TexMCNKChunk chunk)
        {
            var layerCount = chunkSize / 16;

            chunk.LayerCount         = layerCount;
            chunk.TextureIds         = new uint[layerCount];
            chunk.LayerOffsetInMCAL  = new uint[layerCount];
            chunk.AlphaMapCompressed = new bool[layerCount];

            for (var i = 0; i < layerCount; ++i)
            {
                chunk.TextureIds[i] = reader.ReadUInt32();

                var bitArray = new byte[4];
                reader.Read(bitArray, 0, 4);
                var flags = new BitArray(bitArray);
                chunk.AlphaMapCompressed[i] = flags[9];

                chunk.LayerOffsetInMCAL[i] = reader.ReadUInt32();
                var effectId = reader.ReadUInt32();
            }
        }
        /// <summary>
        /// Read Alpha Layers from MCAL.
        /// </summary>
        public static void ReadMCAL(BinaryReader reader, TexMCNKChunk chunk, uint wdtFileDataId, uint chunkSize)
        {
            var mphd = WDTData.MPHDs[wdtFileDataId];

            var mcal = new MCAL[chunk.LayerCount];

            mcal[0] = new MCAL
            {
                Layer = new byte[64 * 64]
            };

            Parallel.For(0, 64 * 64, i => { mcal[0].Layer[i] = 255; });

            var readOffset = 0;

            for (var i = 1; i < chunk.LayerCount; ++i)
            {
                if (chunk.LayerOffsetInMCAL[i] != readOffset)
                {
                    Debug.LogError("Mismatch: layer boefre required more/less bytes than expected");
                }

                if (chunk.AlphaMapCompressed[i])
                {
                    mcal[i] = new MCAL
                    {
                        Layer = new byte[64 * 64]
                    };

                    var inOffset  = 0;
                    var outOffset = 0;
                    while (outOffset < 4096)
                    {
                        var info  = reader.ReadByte(); ++inOffset;
                        var mode  = (uint)(info & 0x80) >> 7;
                        var count = (uint)(info & 0x7F);

                        if (mode != 0)
                        {
                            var val = reader.ReadByte(); ++inOffset;
                            while (count-- > 0 && outOffset < 4096)
                            {
                                mcal[i].Layer[outOffset] = val;
                                ++outOffset;
                            }
                        }
                        else
                        {
                            while (count-- > 0 && outOffset < 4096)
                            {
                                var val = reader.ReadByte(); ++inOffset;
                                mcal[i].Layer[outOffset] = val;
                                ++outOffset;
                            }
                        }
                    }

                    readOffset += inOffset;
                    if (outOffset != 4096)
                    {
                        Debug.LogError($"OutOffset is not 4096! {outOffset}");
                    }
                }
                else if (mphd.Flags.HasFlag(MPHDFlags.AdtHasBigAlpha) || mphd.Flags.HasFlag(MPHDFlags.AdtHasHeightTexturing))
                {
                    mcal[i] = new MCAL
                    {
                        Layer = reader.ReadBytes(4096)
                    };

                    readOffset += 4096;
                }
                else
                {
                    mcal[i] = new MCAL
                    {
                        Layer = new byte[64 * 64]
                    };

                    var mcalData = reader.ReadBytes(2048);
                    readOffset += 2048;

                    for (var j = 0; j < 2048; ++j)
                    {
                        mcal[i].Layer[2 * j + 0] = (byte)(((mcalData[j] & 0x0F) >> 0) * 17);
                        mcal[i].Layer[2 * j + 1] = (byte)(((mcalData[j] & 0xF0) >> 4) * 17);
                    }
                }
            }

            if (readOffset != chunkSize)
            {
                throw new Exception($"ReadOffset is not 4096! {readOffset}");
            }

            chunk.AlphaLayers = mcal;
        }