/*
 * Copyright (C) 2025 Biswapriyo Nath
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

import "wtypes.idl";
#include "mpeg2bits.h"

typedef WORD PID;
typedef BYTE TID;
typedef WORD TEID;
typedef UINT ClientKey;

typedef enum
{
    MPEG_SECTION_IS_NEXT = 0,
    MPEG_SECTION_IS_CURRENT = 1,
} MPEG_CURRENT_NEXT_BIT;

typedef struct
{
    WORD wTidExt;
    WORD wCount;
} TID_EXTENSION, *PTID_EXTENSION;

typedef struct
{
    TID TableId;
    union
    {
        MPEG_HEADER_BITS_MIDL S;
        WORD W;
    } Header;
    BYTE SectionData[1];
} SECTION, *PSECTION;

typedef struct
{
    TID TableId;
    union
    {
        MPEG_HEADER_BITS_MIDL S;
        WORD W;
    } Header;
    TEID TableIdExtension;
    union
    {
        MPEG_HEADER_VERSION_BITS_MIDL S;
        BYTE B;
    } Version;
    BYTE SectionNumber;
    BYTE LastSectionNumber;
    BYTE RemainingData[1];
} LONG_SECTION, *PLONG_SECTION;

typedef struct
{
    TID TableId;
    union
    {
        MPEG_HEADER_BITS_MIDL S;
        WORD W;
    } Header;
    TEID TableIdExtension;
    union
    {
        MPEG_HEADER_VERSION_BITS_MIDL S;
        BYTE B;
    } Version;
    BYTE SectionNumber;
    BYTE LastSectionNumber;
    BYTE ProtocolDiscriminator;
    BYTE DsmccType;
    WORD MessageId;
    DWORD TransactionId;
    BYTE Reserved;
    BYTE AdaptationLength;
    WORD MessageLength;
    BYTE RemainingData[1];
} DSMCC_SECTION, *PDSMCC_SECTION;

typedef struct
{
    DWORD dwLength;
    PSECTION pSection;
} MPEG_RQST_PACKET, *PMPEG_RQST_PACKET;

typedef struct
{
    WORD wPacketCount;
    [size_is(wPacketCount)] PMPEG_RQST_PACKET PacketList[];
} MPEG_PACKET_LIST, *PMPEG_PACKET_LIST;

typedef struct
{
    BOOL fSpecifyProtocol;
    BYTE Protocol;
    BOOL fSpecifyType;
    BYTE Type;
    BOOL fSpecifyMessageId;
    WORD MessageId;
    BOOL fSpecifyTransactionId;
    BOOL fUseTrxIdMessageIdMask;
    DWORD TransactionId;
    BOOL fSpecifyModuleVersion;
    BYTE ModuleVersion;
    BOOL fSpecifyBlockNumber;
    WORD BlockNumber;
    BOOL fGetModuleCall;
    WORD NumberOfBlocksInModule;
} DSMCC_FILTER_OPTIONS;

typedef struct
{
    BOOL fSpecifyEtmId;
    DWORD EtmId;
} ATSC_FILTER_OPTIONS;

typedef struct
{
    BOOL fSpecifySegment;
    BYTE bSegment;
} DVB_EIT_FILTER_OPTIONS;

typedef struct
{
    BYTE bVersionNumber;
    WORD wFilterSize;
    BOOL fUseRawFilteringBits;
    BYTE Filter[16];
    BYTE Mask[16];
    BOOL fSpecifyTableIdExtension;
    WORD TableIdExtension;
    BOOL fSpecifyVersion;
    BYTE Version;
    BOOL fSpecifySectionNumber;
    BYTE SectionNumber;
    BOOL fSpecifyCurrentNext;
    BOOL fNext;
    BOOL fSpecifyDsmccOptions;
    DSMCC_FILTER_OPTIONS Dsmcc;
    BOOL fSpecifyAtscOptions;
    ATSC_FILTER_OPTIONS Atsc;
} MPEG2_FILTER, *PMPEG2_FILTER;

typedef struct
{
    union
    {
        struct
        {
            BYTE bVersionNumber;
            WORD wFilterSize;
            BOOL fUseRawFilteringBits;
            BYTE Filter[16];
            BYTE Mask[16];
            BOOL fSpecifyTableIdExtension;
            WORD TableIdExtension;
            BOOL fSpecifyVersion;
            BYTE Version;
            BOOL fSpecifySectionNumber;
            BYTE SectionNumber;
            BOOL fSpecifyCurrentNext;
            BOOL fNext;
            BOOL fSpecifyDsmccOptions;
            DSMCC_FILTER_OPTIONS Dsmcc;
            BOOL fSpecifyAtscOptions;
            ATSC_FILTER_OPTIONS Atsc;
        };
        BYTE bVersion1Bytes[124];
    };
    BOOL fSpecifyDvbEitOptions;
    DVB_EIT_FILTER_OPTIONS DvbEit;
} MPEG2_FILTER2, *PMPEG2_FILTER2;

cpp_quote("#define MPEG2_FILTER_VERSION_1_SIZE 124")
cpp_quote("#define MPEG2_FILTER_VERSION_2_SIZE 133")

typedef struct
{
    HRESULT hr;
    DWORD dwDataBufferSize;
    DWORD dwSizeOfDataRead;
    [size_is(dwDataBufferSize)] BYTE *pDataBuffer;
} MPEG_STREAM_BUFFER, *PMPEG_STREAM_BUFFER;

typedef struct
{
    BYTE Hours;
    BYTE Minutes;
    BYTE Seconds;
} MPEG_TIME;

typedef MPEG_TIME MPEG_DURATION;

typedef struct
{
    BYTE Date;
    BYTE Month;
    WORD Year;
} MPEG_DATE;

typedef struct
{
    MPEG_DATE D;
    MPEG_TIME T;
} MPEG_DATE_AND_TIME;

typedef enum
{
    MPEG_CONTEXT_BCS_DEMUX,
    MPEG_CONTEXT_WINSOCK,
} MPEG_CONTEXT_TYPE;

typedef struct
{
    DWORD AVMGraphId;
} MPEG_BCS_DEMUX;

typedef struct
{
    DWORD AVMGraphId;
} MPEG_WINSOCK;

typedef struct
{
    MPEG_CONTEXT_TYPE Type;
    union
    {
        MPEG_BCS_DEMUX Demux;
        MPEG_WINSOCK Winsock;
    } U;
} MPEG_CONTEXT, *PMPEG_CONTEXT;

typedef enum
{
    MPEG_RQST_UNKNOWN = 0,
    MPEG_RQST_GET_SECTION,
    MPEG_RQST_GET_SECTION_ASYNC,
    MPEG_RQST_GET_TABLE,
    MPEG_RQST_GET_TABLE_ASYNC,
    MPEG_RQST_GET_SECTIONS_STREAM,
    MPEG_RQST_GET_PES_STREAM,
    MPEG_RQST_GET_TS_STREAM,
    MPEG_RQST_START_MPE_STREAM,
} MPEG_REQUEST_TYPE;

typedef struct
{
    MPEG_REQUEST_TYPE Type;
    MPEG_CONTEXT Context;
    PID Pid;
    TID TableId;
    MPEG2_FILTER Filter;
    DWORD Flags;
} MPEG_SERVICE_REQUEST, *PMPEG_SERVICE_REQUEST;

typedef struct
{
    DWORD IPAddress;
    WORD Port;
} MPEG_SERVICE_RESPONSE, *PMPEG_SERVICE_RESPONSE;

typedef struct _DSMCC_ELEMENT
{
    PID pid;
    BYTE bComponentTag;
    DWORD dwCarouselId;
    DWORD dwTransactionId;
    struct _DSMCC_ELEMENT *pNext;
} DSMCC_ELEMENT, *PDSMCC_ELEMENT;

typedef struct _MPE_ELEMENT
{
    PID pid;
    BYTE bComponentTag;
    struct _MPE_ELEMENT *pNext;
} MPE_ELEMENT, *PMPE_ELEMENT;

typedef struct _MPEG_STREAM_FILTER
{
    WORD wPidValue;
    DWORD dwFilterSize;
    BOOL fCrcEnabled;
    BYTE rgchFilter[16];
    BYTE rgchMask[16];
} MPEG_STREAM_FILTER;
