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

namespace skyscraper5.src.InteractionChannel.Model.Descriptors
{
	[SkyscraperPlugin]
	[TsDescriptor(0xb2,"TIM")]
	public class _0xb2_ReturnTransmissionModesDescriptor : TsDescriptor
	{
		public _0xb2_ReturnTransmissionModesDescriptor(byte[] buffer) 
		{
			MemoryStream ms = new MemoryStream(buffer, false);
			byte superframeIdLoopCount = ms.ReadUInt8();

			int spaceRequired = superframeIdLoopCount * 5;
			if (ms.GetAvailableBytes() < spaceRequired)
			{
				Valid = false;
				return;
			}

			Superframes = new Superframe[superframeIdLoopCount];
			for (int i = 0; i < superframeIdLoopCount; i++)
			{
				Superframes[i] = new Superframe();
				Superframes[i].SuperframeId = ms.ReadUInt8();

				byte bytea = ms.ReadUInt8();
				Superframes[i].ScramblingSequenceIndex = (bytea & 0x03);
				Superframes[i].ScramblingSequenceIndex <<= 16;
				Superframes[i].ScramblingSequenceIndex += ms.ReadUInt16BE();

				byte transmissionModeCount = ms.ReadUInt8();
				Superframes[i].TransmissionModes = new TransmissionMode[transmissionModeCount];
				for (int j = 0; j < transmissionModeCount; j++)
				{
					Superframes[i].TransmissionModes[j] = new TransmissionMode();
					Superframes[i].TransmissionModes[j].InnerCodePuncturing = ms.ReadUInt8() & 0x0f;
					Superframes[i].TransmissionModes[j].Modulation = ms.ReadUInt8() & 0x1f;
					Superframes[i].TransmissionModes[j].TimeslotPayloadType = ms.ReadUInt8();

					byte byteb = ms.ReadUInt8();
					Superframes[i].TransmissionModes[j].EsNoThresholdFlag = (byteb & 0x80) != 0;
					Superframes[i].TransmissionModes[j].EsNoThreshold = (byteb & 0x7f);
				}
			}
			Valid = true;
		}

		public Superframe[] Superframes { get; }
		public class Superframe
		{
			public byte SuperframeId { get; internal set; }
			public int ScramblingSequenceIndex { get; internal set; }
			public TransmissionMode[] TransmissionModes { get; internal set; }
		}

		public class TransmissionMode
		{
			public int InnerCodePuncturing { get; internal set; }
			public int Modulation { get; internal set; }
			public byte TimeslotPayloadType { get; internal set; }
			public bool EsNoThresholdFlag { get; internal set; }
			public int EsNoThreshold { get; internal set; }
		}

		public override string ToString()
		{
			return String.Format("Return Transmission Modes for {0} superframes.", Superframes.Length);
		}
	}
}
