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

namespace skyscraper5.Dvb.Descriptors.Extension
{
	[SkyscraperPlugin]
	[ExtensionDescriptor(0x19,"PMT")]
    public class AudioPreselectionDescriptor : Dvb.ExtensionDescriptor
    {
        public AudioPreselectionDescriptor(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer, false);
            int numPreselections = (ms.ReadUInt8() & 0xf8) >> 3;
            Preselections = new AudioPreselection[numPreselections];
            for (int i = 0; i < numPreselections; i++)
            {
                AudioPreselection child = new AudioPreselection();
                Preselections[i] = child;
                
                byte readUInt8 = ms.ReadUInt8();
                child.PreselectionId = (readUInt8 & 0xf8) >> 3;
                child.AudioRenderingIndication = (AudioPreselection.RenderingIndication)(readUInt8 & 0x07);

                readUInt8 = ms.ReadUInt8();
                child.AudioDescription = (readUInt8 & 0x80) != 0;
                child.SpokenSubtitles = (readUInt8 & 0x40) != 0;
                child.DialogueEnhancement = (readUInt8 & 0x20) != 0;
                child.InteractivityEnabled = (readUInt8 & 0x10) != 0;
                bool languageCodePresent = (readUInt8 & 0x08) != 0;
                bool textLabelPresent = (readUInt8 & 0x04) != 0;
                bool multiStreamPresent = (readUInt8 & 0x02) != 0;
                bool futureExtension = (readUInt8 & 0x01) != 0;
                if (languageCodePresent)
                    child.Iso639LangaugeCode = Encoding.ASCII.GetString(ms.ReadBytes(3));
                if (textLabelPresent)
                    child.MessageId = ms.ReadUInt8();
                if (multiStreamPresent)
                {
                    int numAuxComponents = (ms.ReadUInt8() & 0xe0) >> 5;
                    child.ComponentTags = ms.ReadBytes(numAuxComponents);
                }

                if (futureExtension)
                {
                    int futureExtensionLength = ms.ReadUInt8() & 0x1f;
                    child.FutureExtension = ms.ReadBytes(futureExtensionLength);
                }
            }
        }

        public AudioPreselection[] Preselections { get; private set; }

        public class AudioPreselection
        {
            public int PreselectionId { get; set; }
            public RenderingIndication AudioRenderingIndication { get; set; }
            public bool AudioDescription { get; set; }
            public bool SpokenSubtitles { get; set; }
            public bool DialogueEnhancement { get; set; }
            public bool InteractivityEnabled { get; set; }
            public string Iso639LangaugeCode { get; set; }
            public byte MessageId { get; set; }
            public byte[] ComponentTags { get; set; }
            public byte[] FutureExtension { get; set; }

            public enum RenderingIndication : byte
            {
                NoPreference = 0,
                Stereo = 1,
                TwoDimensional = 2,
                ThreeDimensional = 3,
                Headphones = 4
            }
        }
    }
}
