/**
 * @file SDT.h
 *
 */

#pragma once

#include "mpeg2/ts/Table.h"

namespace MPEG2
{
namespace TS
{

/*
#define MPEG2_TS_SDT_SELF       "Self"
#define MPEG2_TS_SDT_OTHER      "Other"
#define MPEG2_TS_SDT_SERVICES   "Services"
#define MPEG2_TS_SDT_SERVICE_ID "ServiceID"
#define MPEG2_TS_SDT_TYPE       "Type"
#define MPEG2_TS_SDT_NAME       "Name"
*/

#define MAXSECLEN 4096

typedef struct _SDThead {
	char table_id;
	int  section_syntax_indicator;
	int  reserved_future_use1;
	int  reserved1;
	int  section_length;
	int  transport_stream_id;
	int  reserved2;
	int  version_number;
	int  current_next_indicator;
	int  section_number;
	int  last_section_number;
	int  original_network_id;
	int  reserved_future_use2;
} SDThead;

typedef struct _SDTbody {
	int  service_id;
	int  reserved_future_use1;
	int  EIT_user_defined_flags;
	int  EIT_schedule_flag;
	int  EIT_present_following_flag;
	int  running_status;
	int  free_CA_mode;
	int  descriptors_loop_length;
} SDTbody;

typedef struct _SVCdesc {
	int  descriptor_tag;
	int  descriptor_length;
	int  service_type;
	int  service_provider_name_length;
	char service_provider_name[MAXSECLEN];
	int  service_name_length;
	char service_name[MAXSECLEN];
} SVCdesc;

class SDT : public Table
{
protected:
    bool decode_section();

public:
    uint8_t     _table_id;                          //  8
    uint8_t     _section_syntax_indicator;          //  1
                                                    //  1   '1'
                                                    //  2   '11'
    uint16_t    _section_length;                    // 12
    uint16_t    _transport_stream_id;               // 16
                                                    //  2   '11'
    uint8_t     _version_number;                    //  5
    uint8_t     _current_next_indicator;            //  1
    uint8_t     _section_number;                    //  8
    uint8_t     _last_section_number;               //  8
    uint16_t    _original_network_id;               // 16
                                                    //  8
    uint16_t    _service_count;
    struct _service
    {
        uint16_t    _service_id;                    // 16
                                                    //  3
        uint8_t     _EIT_user_defined_flags;        //  3
        uint8_t     _EIT_schedule_flag;             //  1
        uint8_t     _EIT_present_following_flag;    //  1
        uint8_t     _running_status;                //  3
        uint8_t     _free_CA_mode;                  //  1
        uint16_t    _descriptors_loop_length;       // 12
        uint8_t *   _descriptor;                    //  N

        SVCdesc *   _desc;
    } *_services;

public:
    SDT();
    SDT(SDT &sdt);
    ~SDT();
    void reset();
};

} // TS
} // MPEG2
