using skyscraper5.Dvb.Psi;
using skyscraper5.Mpeg2;
using skyscraper5.Mpeg2.Psi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace skyscraper8.DvbSis
{
    internal class SisPsiHandler : IPsiProcessor
    {
        public SisPsiHandler(SisHandler handler, ushort parentProgram) 
        { 
            _handler = handler;
            _parentProgram = parentProgram;
        }

        private SisHandler _handler;
        private ushort _parentProgram;

        public void GatherPsi(PsiSection section, int sourcePid)
        {
            switch (section.TableId)
            {
                case 0x00:
                    SisPatContainer patContainer = new SisPatContainer();
                    PatParser patParser = new PatParser(patContainer);
                    patParser.GatherPsi(section, 0);
                    _handler.OnSisPat(sourcePid, _parentProgram, patContainer);
                    break;
                case 0x01:
                    SisCatContainer catContainer = new SisCatContainer();
                    CatParser catParser = new CatParser(catContainer);
                    catParser.GatherPsi(section, 0);
                    _handler.OnSisCat(sourcePid, _parentProgram, catContainer);
                    break;
                case 0x02:
                    SisPmtContainer pmtContainer = new SisPmtContainer();
                    PmtParser pmtParser = new PmtParser(pmtContainer);
                    pmtParser.GatherPsi(section, 0);
                    _handler.OnSisPmt(sourcePid, _parentProgram, pmtContainer);
                    break;
                case 0x40:
                    SisNitContainer nitContainer = new SisNitContainer();
                    NitParser nitParser = new NitParser(nitContainer);
                    nitParser.GatherPsi(section, 0);
                    _handler.OnSisNit(sourcePid, _parentProgram, nitContainer);
                    break;
                case 0x42:
                    SisSdtContainer sdtContainer = new SisSdtContainer();
                    SdtParser sdtParser = new SdtParser(sdtContainer);
                    sdtParser.GatherPsi(section, 0);
                    _handler.OnSisSdt(sourcePid, _parentProgram, sdtContainer);
                    break;
                case 0x4e:
                case 0x50:
                    SisEitContainer eitContainer = new SisEitContainer();
                    EitParser eitParser = new EitParser(eitContainer);
                    eitParser.GatherPsi(section, sourcePid);
                    _handler.OnSisEit(sourcePid, _parentProgram, eitContainer);
                    break;
                case 0x70:
                    SisTdtContainer tdtContainer = new SisTdtContainer();
                    TimetableParser tdtParser = new TimetableParser(tdtContainer, null);
                    tdtParser.GatherPsi(section, sourcePid);
                    _handler.OnSisTdt(sourcePid, _parentProgram, tdtContainer);
                    break;
                case 0x73:
                    SisTotContainer totContainer = new SisTotContainer();
                    TimetableParser totParser = new TimetableParser(null, totContainer);
                    totParser.GatherPsi(section, sourcePid);
                    _handler.OnSisTot(sourcePid, _parentProgram, totContainer);
                    break;
                default:
                    throw new NotImplementedException(String.Format("Table ID 0x{0:X2} in DVB-SIS PSI/SI not supported yet. To get this fixed, please share a sample of this stream.", section.TableId));
            }
        }
    }
}
