#pragma once
#include "Lock.h"
#include "DateTime.h"
#include <map>
#include <vector>

#ifdef _DEBUG
//	#define TSEITPARSER_DEBUG_PRINT
#endif

#define TSEPG_EVENT_TITLE_MAX	256
#define TSEPG_EVENT_TEXT_MAX	1024
#define MAX_SHARE_EVENT			16

struct TSEPG_PROGRAM
{
	BYTE	byType;			// データタイプ(小さい値のほうが、情報優先度が高い)
							// 1=p/f Actualにて受信 2=p/f otherbにて受信 3=schedule Actualにて受信 4=Schedule other にて受信
	BYTE	byVersion;		// データのバージョン

	WORD	wServiceID;		// サービスID
	WORD	wEventID;		// イベントID
	WORD	wSecNo;

	char	szTitle[TSEPG_EVENT_TITLE_MAX+1];	// タイトル
	char	szText[TSEPG_EVENT_TEXT_MAX+1];	// 説明

	DateTime stStart;		// 開始時間
	DateTime stEnd;			// 終了時間
	DWORD	dwDuration;		// 番組長(全ビット=1の場合、終了未定)

	// 以下はまだ未定
	struct {
		BYTE byVideoType;		// 映像コンポーネントタイプ
		BYTE byAudioType;		// 音声コンポーネントタイプ

	} stComponent;
};

typedef std::map<WORD,struct TSEPG_PROGRAM>		TSEpg_Map;				// Key=イベントID , Val=番組ごとの情報
typedef std::vector<struct TSEPG_PROGRAM>		TsEpg_Vector;
typedef std::pair<WORD,struct TSEPG_PROGRAM>	TSEpg_MapPair;
typedef std::map<WORD,TSEpg_Map*>				TSEpg_ServiceMap;		// Key=サービスID , Val=サービスごとの番組表
typedef std::pair<WORD,TSEpg_Map*>				TSEpg_ServiceMapPair;

#define TSEPG_COMPONENT_VIDEO_D1					0x00	// D1(480i)
#define TSEPG_COMPONENT_VIDEO_D2					0xA0	// D2(480p)
#define TSEPG_COMPONENT_VIDEO_D3					0xB0	// D3(1080i)
//#define TSEPG_COMPONENT_VIDEO_D4					0x00	// D4(720p) 値は不明
//#define TSEPG_COMPONENT_VIDEO_D5					0x00	// D5(1080p)値は不明
#define TSEPG_COMPONENT_VIDEO_ASPECT_4_3			0x01	// 4:3
#define TSEPG_COMPONENT_VIDEO_ASPECT_16_9			0x03	// 16:9(パンベクトル無し)
#define TSEPG_COMPONENT_VIDEO_ASPECT_16_9_OVER		0x04	// 16:9以上

#define TSEPG_COMPONENT_AUDIO_MONO			0x01
#define TSEPG_COMPONENT_AUDIO_DUAL_MONO		0x02
#define TSEPG_COMPONENT_AUDIO_STEREO		0x03
#define TSEPG_COMPONENT_AUDIO_4CH			0x07
#define TSEPG_COMPONENT_AUDIO_5CH			0x08
#define TSEPG_COMPONENT_AUDIO_5_1CH			0x09

//////////////////////////////////////////////////////////////////////
// EPGデータ管理クラス
class CTsEPGMgr
{
public:
	CTsEPGMgr(void);
	~CTsEPGMgr(void);

	void Clear();

	TSEpg_Map* GetEpgMap(WORD wServiceID,BOOL bNewFlg=FALSE);

	BOOL SetEpgData(WORD wServiceID,struct TSEPG_PROGRAM *pstNewData);
	struct TSEPG_PROGRAM* FindEpgDataByTime(WORD wServiceID,DateTime &stSearch,BOOL bDeleteMode=FALSE);
	struct TSEPG_PROGRAM* FindEpgDataByEventID(WORD wNetworkID,WORD wStreamID,WORD wServiceID,WORD wEventID);
	struct TSEPG_PROGRAM* FindEpgDataByTitle(LPCTSTR title,DWORD len,WORD wServiceID);
	struct TSEPG_PROGRAM* FindEpgDataLatest(WORD wServiceID);
	void FreeEpgDataMemory(struct TSEPG_PROGRAM *pData,int iCount);
	void DeleteEpgDataByTime(DateTime &stDeleteTime,WORD wServiceID=0xFFFF);

	static int TsEitParser(struct TSEPG_PROGRAM **ppstProg,int *piCount,BYTE byTableID,BYTE byVersion,WORD wServiceID,WORD wSecNO,BYTE *pData);

	static void FreeTsEitParserMemory(struct TSEPG_PROGRAM *pstProg,int iCount);
#ifdef TSEITPARSER_DEBUG_PRINT
	static void TsEitParser_DebugPrintProgram(BOOL bActual,struct TS_section_header &stSecHeader,struct TSEPG_PROGRAM &stProg);
#else 
	static inline void TsEitParser_DebugPrintProgram(BOOL bActual,struct TS_section_header &stSecHeader,struct TSEPG_PROGRAM &stProg) { /*何もしない*/}
#endif
	int Is2ByteChar(unsigned char c);
	DWORD CompChar(BYTE* str1,BYTE* str2);

protected:
	LOCK_OBJ	m_EpgLock;
	TSEpg_ServiceMap	m_EpgDB;

	struct TSEPG_PROGRAM* GetEpgData(TSEpg_Map *pEpg,WORD wEventID);
};
