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

namespace skyscraper5.Dvb.TvAnytime
{
    public class DvbBinaryLocator
    {
        public DvbBinaryLocator(MemoryStream ms)
        {
            ushort readUInt16Be = ms.ReadUInt16BE();
            IdentifierType = (readUInt16Be & 0xc000) >> 14;
            ScheduledTimeReliability = (readUInt16Be & 0x2000) != 0;
            InlineService = (readUInt16Be & 0x1000) != 0;
            this.Reserved = (readUInt16Be & 0x0800) != 0;
            StartDate = (readUInt16Be & 0x07fc) >> 2;
            if (!InlineService)
            {
                DvbServiceTripletId = (readUInt16Be & 0x0003);
                DvbServiceTripletId <<= 8;
                DvbServiceTripletId += ms.ReadUInt8();
            }
            else
            {
                TransportStreamId = ms.ReadUInt16BE();
                OriginalNetworkId = ms.ReadUInt16BE();
                ServiceId = ms.ReadUInt16BE();
            }

            StartTime = ms.ReadUInt16BE();
            Duration = new TimeSpan(0, 0, ms.ReadUInt16BE() * 2);

            if (IdentifierType == 1)
            {
                EventId = ms.ReadUInt16BE();
            }

            if (IdentifierType == 2)
            {
                TvaId = ms.ReadUInt16BE();
            }

            if (IdentifierType == 3)
            {
                TvaId = ms.ReadUInt16BE();
                Component = ms.ReadUInt8();
            }

            if (IdentifierType == 0 && ScheduledTimeReliability)
            {
                byte readUInt8 = ms.ReadUInt8();
                EarlyStartWindow = (readUInt8 & 0xe0) >> 5;
                LateEndWindow = (readUInt8 & 0x1f);
            }
        }

        public int? LateEndWindow { get; set; }

        public int? EarlyStartWindow { get; set; }

        public byte? Component { get; set; }

        public ushort? TvaId { get; set; }

        public ushort? EventId { get; set; }

        public TimeSpan Duration { get; set; }

        public ushort StartTime { get; set; }

        public ushort? ServiceId { get; set; }

        public ushort? OriginalNetworkId { get; set; }

        public ushort? TransportStreamId { get; set; }

        public int? DvbServiceTripletId { get; private set; }

        public int StartDate { get; private set; }

        public bool Reserved { get; private set; }

        public bool InlineService { get; private set; }

        public bool ScheduledTimeReliability { get; private set; }

        public int IdentifierType { get; private set; }
    }
}
