using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Skyscraper.IO;
using skyscraper5.Skyscraper.Plugins;

namespace skyscraper5.T2MI.Packets
{
	[SkyscraperPlugin]
	[T2MiPacketType(0x02)]
    public class _0x02_ArbitraryCellInsertion : T2MiPacket
    {
        public _0x02_ArbitraryCellInsertion(T2MIHeader header, byte[] buffer) : base(header, buffer)
        {
            if (buffer.Length < 8)
            {
                Valid = false;
                return;
            }
            MemoryStream ms = new MemoryStream(buffer, true);
            FrameIndex = ms.ReadUInt8();
            TxIdentifier = ms.ReadUInt16BE();
            ushort rfu = ms.ReadUInt16BE();
            StartCellAddress = (ms.ReadUInt8() & 0x3f);
            StartCellAddress <<= 8;
            StartCellAddress += ms.ReadUInt8();
            StartCellAddress <<= 8;
            StartCellAddress += ms.ReadUInt8();
            StartCellAddress <<= 8;

            long numSamples = ms.GetAvailableBytes();
            numSamples *= 8;
            numSamples /= 24;
            IQ = new Tuple<int, int>[numSamples];

            for (long sample = 0; sample < numSamples; sample++)
            {
                byte bq1 = ms.ReadUInt8();
                byte bq2 = ms.ReadUInt8();
                byte bq3 = ms.ReadUInt8();

                int i = bq1;
                i <<= 4;
                i += ((bq2 & 0xf0) >> 4);
                if ((i & 0x00000800) != 0)
                    i = -1 & i;

                int q = bq2 & 0x0f;
                q <<= 8;
                q += bq3;
                if ((i & 0x00000800) != 0)
                    q = -1 & i;

                IQ[sample] = new Tuple<int, int>(i, q);
            }

            Valid = true;
        }

        public Tuple<int, int>[] IQ { get; private set; }

        public int StartCellAddress { get; private set; }

        public ushort TxIdentifier { get; private set; }

        public byte FrameIndex { get; private set; }
    }
}
