/****************************************************************************
**                                                                          **
**  Template file for implementing Multidec API helpers                     **
**  Supports: MD 8.0, 8.1 and 8.2 (API 1.02)                                **
**  Base class definition                                                   **
**  Visual C++ 6                                                            **
**                                                                          **
**  (C) Vlinders, June 2002, V 1.00                                         **
**                                                                          **
 ****************************************************************************/

/*

  How to use:
  -----------

  derive you own class from public CAPI_Impl, and implement some/all of the virtual
  functions to customize the behaviour

  Define TTTRICK to allow using DebiOut16 function directly in TTDVBACC for ProgDVB
  or WTVP.

*/

#define TTTRICK
#ifndef _API_IMPL_H_
#define _API_IMPL_H_
#include "MDExtern.h"

// These defines and structures are not supported by MD, so they are not in MDExtern
// WTVP
#define WTVP_CHANNELS_COUNT			 0x01021000
#define WTVP_GET_VOLUME				 0x01021010
#define WTVP_SET_VOLUME				 0x01021011
#define	WTVP_SEND_DISEQC			 0x01021015
#define WTVP_MOVE_OSD				 0x01021020
#define WTVP_GET_TIMERRECORD	 	 0x01021050
#define WTVP_SET_TIMERRECORD		 0x01021055
/*
#define WTVP_READ_REGISTRY			 0x01021046
#define WTVP_WRITE_REGISTRY			 0x01021045
#define WTVP_SET_OSD_SURFACE		 0x01021065
*/
#define WTVP_TIMER_RECORD		0
#define WTVP_TIMER_SWITCH		1
#define WTVP_TIMER_WEEK			2
#define WTVP_TIMER_WEEKEND		3
#define WTVP_TIMER_DAILY		4
#define WTVP_TIMER_MONDAY		5
#define WTVP_TIMER_TUESDAY		6
#define WTVP_TIMER_WEDNESDAY	7
#define	WTVP_TIMER_THURSDAY		8
#define WTVP_TIMER_FRIDAY		9
#define	WTVP_TIMER_SATURDAY		10
#define WTVP_TIMER_SUNDAY		11

// PROGDVB
#define  PROGAPI_GET_SIGNAL_LEVEL    0x01022001

// --- ProgDVB things -------------------------------

typedef struct 
{
	DWORD   dwLength;	// Length of this structure
	DWORD   dwQuality;	// Quality: 0-100
	DWORD   dwLevel;	// Level: 0-100
} TProgAPISignalState;

typedef struct  
{
	DWORD dwSize;
	DWORD dwResult;
	DWORD dwCmdLength;
	BYTE  Cmd[16];
} TProgAPIDiSEqCmd;

// --- WTVP things -----------------------------------

typedef struct 
{
	unsigned char message[6];  // max 6 bytes 
} WTVP_DiseqcStruc;

typedef struct
{
        int     x;
        int y;
} WTVP_OSD_MOVE;

typedef struct
{
	int	Start;			//time_t (32Bit) the number of seconds elapsed since midnight (00:00:00), January 1, 1970
	int	Stop;			//time_t (32Bit) the number of seconds elapsed since midnight (00:00:00), January 1, 1970
	char	Sendung[64];	//
	char	Sender[32];		//
	int		iChannelNumber; // 
	bool	bFav;			//  redundant
	int		iRecordingType; //  TIMER_xxx defined
} WTVP_TimerData;

typedef struct
{
	int				iTimerNumber;
	int				iTimerCount;
	WTVP_TimerData  theTimerData;
} WTVP_TimerRecord;


// --- TechnoTrend support ----------------------------

#ifdef TTTRICK

typedef void (*p_InitDvbApiDll)(void);
typedef BOOL (*p_DebiOut16)(unsigned short, unsigned short);
typedef unsigned short (*p_DebiIn16)(unsigned short);
typedef unsigned long (*p_GetLastDebiError)(void);
extern p_InitDvbApiDll		InitDvbApiDll;
extern p_DebiOut16			DebiOut16;
extern p_DebiIn16			DebiIn16;
extern p_GetLastDebiError	GetLastDebiError;

#endif

typedef enum {TT_UNKNOWN,TT_206, TT_207, TT_208B, TT_208C, TT_209, TT_210, TT_210B } TT_VersionNumber_t;

#define TT_DPRAM_BASE		0x4000
#define TT_DVB_COMMAND		(TT_DPRAM_BASE+0x0FC)

extern HMODULE			hTT;					// Handle on TTDVBACC.dll module

// Some globals variables
extern char				CallerName[_MAX_PATH];
extern char				curPath[_MAX_PATH];
extern char				dlldirPath[_MAX_PATH];

typedef struct TProgramm82 MyProgram_t;

extern "C" void to_log(char *x);
class CAPI_Impl
{
public:
	friend DWORD WINAPI ThreadLauncher(LPVOID arg);
	// Typedef of thread function (Create_Osd_Thread) 
	typedef void (CAPI_Impl::*THREADSTARTProc)(void);

	CAPI_Impl();
	virtual ~CAPI_Impl();

	void CopyFrom80(MyProgram_t *dest, TProgramm80*from);

	// Called when the plugin is loaded
	virtual BOOL DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved);

	// Override 
	virtual void to_log(char *x);

// Functions called by MD
	// OnStart: called after plugin is loaded
	//			MDInstance: handle to calling module
	//			MDWnd: handle to Multidec windows (for sending messages)
	//			Log_Set: 1 if LOG is selected in Multidec.ini
	//			DLL_ID: id of this DLL for Multidec
	//			*My_Hot_Key: assignable hotkey of this plugin
	//			Api_Version: identifier of the calling API version (not in MD8.0 and MD8.1)
	//			*Keep_me_running: 0 to keep the plugin in memory, any other unloads (not in MD8.0 and MD8.1)
	//			Caller API is detected:
	//			MDAPIFlag/MDAPIVer are set     if Api_Version "MD-API Version MM.mm Root dddddd"
	//			PROGAPIFlag/PROGAPIVer are set if Api_Version "MD-API Version xx.xx - MM.mm"
	//			WTVPAPIFlag/WTVPAPIVer are set if GetVersion is "WTVP API-Version MM.mm" or "WTVP-API Version MM.mm"
	//			UseTT is set only if WTVP is detected, as other programs support DVB_COMMAND
 
	virtual void On_Start(HINSTANCE MDInstance, HWND MDWnd, BOOL Log_Set, int DLL_ID, char *My_Hot_Key,char *Api_Version, int *Keep_me_running );

	// OnExit: called by Multidec before exiting, you can do cleanup here
	virtual void On_Exit(HINSTANCE MDInstance, HWND MDWnd, BOOL Log_Set);

	// On_Send_DLL_ID_Name: called by Multidec on initialization to know the name of the Plugin (for the Menu)
	virtual void On_Send_Dll_ID_Name(char *Name);

	// On_Menu_Select: called when a menu in Multidec is selected (in any plugin !)
	//			The IDs are taken from the MENU resource "EXTERN"
	virtual void On_Menu_Select(unsigned int MenuID );

	// On_Channel_Change: called *after* Multidec has tuned to a new channel
	//			CurrentProgramm may actually be a TProgramm80 or 82, and is converted to a 82 internally
	virtual void On_Channel_Change( const struct TProgramm82 &CurrentProgramm );

	// On_Hot_Key: called if hot-key of this plugin is pressed
	virtual void On_Hot_Key( void );

	// On_Rec_Play: called when a play/record function is started/stopped in Multidec
	//			Mode: RECPLAY_PLAY: playback started
	//				  RECPLAY_RECORD: record started
	//				  RECPLAY_STOP: play/record stopped
	virtual void On_Rec_Play(RECPLAY_t Mode);

	// On_Osd_Key: called when a (numeric 0-9) key is pressed while in OSD mode
	virtual void On_Osd_Key( unsigned char Key );
	
	// On_Key_Down: called by WTVP on *each* key press
	virtual int On_Key_Down( UINT nChar, UINT nRepCnt, UINT nFlags );

	// On_Filter_Close: called when MD notifies that a filter has been close
	//			FilterOffset: filter number (ID)
	virtual void On_Filter_Close(unsigned int FilterOffset );

	// Callback from filter
	virtual void  On_Filter_Data_Arrival(int MyFilter, int DataLen, unsigned char *_Data);

// Helpers Plugin calling MD functions
	// Get_MDAPI_Version: get the API version if available, return 0 if not supported, 1 otherwise
	int Get_MDAPI_Version(char *version);							// MDAPI_GET_VERSION (since 1.02)
	int Set_Current_Transponder(struct TTransponder *Transponder);	// MDAPI_SET_TRANSPONDER
	int Get_Current_Transponder(struct TTransponder *Transponder);	// MDAPI_GET_TRANSPONDER

	int Get_Current_Programm( struct TProgrammNummer *TPNr );		// MDAPI_GET_PROGRAMM_NUMMER
	int Set_Current_Programm( int Nummer );							// MDAPI_SET_PROGRAMM_NUMMER

	int Get_Programm_Detail80( struct TProgramm80 *TPtg);			// MDAPI_GET_PROGRAMM
	int Set_Programm_Detail80( struct TProgramm80 *TPtg);			// MDAPI_SET_PROGRAMM
	int Get_Programm_Detail( struct TProgramm82 *TPtg);
	int Set_Programm_Detail( struct TProgramm82 *TPtg);

	int Save_Programm_Liste( void );								// MDAPI_SAVE_PROGRAMM
	int Rescan_Programm( struct TProgramm82 *TPtg);					// MDAPI_RESCAN_PROGRAMM

	int Start_Filter(struct TSTART_FILTER *sf);						// MDAPI_START_FILTER
	int	Stop_Filter(int filterid);									// MDAPI_STOP_FILTER

	int Start_CAPIFilter(void *obj, struct TSTART_FILTER *sf);


	// newprograms is a TProgramxx array of TPSIZE elements that *you* allocate
	int Scan_Current_TP80(TProgramm80 *newprograms);				// MDAPI_SCAN_CURRENT_TP
	int Scan_Current_TP(TProgramm82 *newprograms);					// MDAPI_SCAN_CURRENT_TP

	int Scan_Current_CAT(struct TTPCatio82  *CurrentCat);			// MDAPI_SCAN_CURRENT_CAT
	
	// OSD functions
	int OSD_CreateWindow(unsigned char Bits, unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,BOOL Has_KeyBoard_Input);
																							// MDAPI_START_OSD
	int OSD_Draw_Block(unsigned short x,unsigned short y,unsigned short SizeX,unsigned short SizeY,unsigned short Color);											
																							// MDAPI_OSD_DRAWBLOCK
	int OSD_Set_Font(unsigned short Typ,unsigned short Fg_Color,unsigned short Bg_Color); 	// MDAPI_OSD_SETFONT
	int OSD_Write_Text(unsigned short x,unsigned short y,const char *Text);				// MDAPI_OSD_TEXT
	int OSD_Send_Key(unsigned char Key);													// MDAPI_SEND_OSD_KEY
	int OSD_Close();																		// MDAPI_STOP_OSD

	// Subclassing WTVP Window
	int		APISubclassWindow();
	int		APIUnSubclassWindow();
	virtual LRESULT APIWndProc(UINT, WPARAM, LPARAM); 
	friend  LRESULT CALLBACK f_MyAPIWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
	friend  BOOL CALLBACK EnumChildWndProc(HWND hwnd, LPARAM lparam);
	// Create a processing thread (in your derived class).
	void Create_Osd_Thread(LPVOID obj,THREADSTARTProc f);

// Helpers for WTVP/PROGDVB API
	int  WTVP_GetTimerRecord( WTVP_TimerRecord *timrec);
	int  WTVP_SetTimerRecord( WTVP_TimerRecord *timrec);
	int  WTVP_Send_Diseqc( const WTVP_DiseqcStruc& ds);
	BYTE WTVP_ReadVolume();
	int  WTVP_SetVolume(BYTE bVolume);
	int  WTVP_GetChannelCount();

	// ProgDVB
	int PROG_Get_Signal_Level( TProgAPISignalState *sig);
	int PROG_Send_Diseqc( TProgAPIDiSEqCmd& ds);
// Various helpers
	BOOL WritePrivateProfileInt(LPCTSTR section, LPCTSTR keyname, int value, LPCTSTR ini);
	// Send a DVB_COMMAND using the direct TT
	void SendTTCommand(TDVB_COMMAND dvb);
	// Send a DVB_COMMAND using MD-API call
	void SendMDCommand(TDVB_COMMAND dvb);

//  Members access
	int MDVersionMajor() const { return (m_MDAPIVer>>8)&0xFF; }
	int MDVersionMinor() const { return m_MDAPIVer&0xFF; }
	int MDAPIFlag() const { return m_MDAPIFlag; }

	int WTVPVersionMajor() const { return (m_WTVPAPIVer>>8)&0xFF; }
	int WTVPVersionMinor() const { return m_WTVPAPIVer&0xFF; }
	int WTVPAPIFlag() const { return m_WTVPAPIFlag; }

	int PROGVersionMajor() const { return (m_PROGAPIVer>>8)&0xFF; }
	int PROGVersionMinor() const { return m_PROGAPIVer&0xFF; }
	int PROGAPIFlag() const { return m_PROGAPIFlag; }

	int DVBxVersionMajor() const { return (m_DVBxAPIVer>>8)&0xFF; }
	int DVBxVersionMinor() const { return m_DVBxAPIVer&0xFF; }
	int DVBxAPIFlag() const { return m_DVBxAPIFlag; }
	
	bool UseTT() const { return m_UseTT; }
	const char *TTVersionAsString() const { return m_TTVersionAsString; }


protected:
	HINSTANCE	m_hDLL;					// Handle to this DLL
	HINSTANCE	m_MultiDecInstance;		// Handle to Calling program (Multidec)
	HWND		m_MultiDecWindow;		// HWND of Calling Window
	BOOL		m_MultiDecLog;			// Log flag
	int			m_MultiDec_DLL_ID;		// ID of this DLL for Calling program
	HANDLE		m_OSD_KEY_EVENT;
	char		m_OSD_Key_Value;
	int			m_MDAPIFlag:1;			// New MD>=8.2 API:1		Old<8.2:0
	int			m_WTVPAPIFlag:1;		// WatchTVPro API detected:1
	int			m_PROGAPIFlag:1;		// ProgDVB API Detected
	int			m_DVBxAPIFlag:1;
	int			m_MDAPIVer;				// Version MDAPI: MM.mm	(in hex)
	int			m_WTVPAPIVer;			// Version WTVPAPI: MM.mm (in decimal!)
	int			m_PROGAPIVer;			// Version PROGDVB: MM.mm (decimal)
	int			m_DVBxAPIVer;			// Version DVBx-API Version MM.mm
	bool		m_UseTT;				// Use TT Debi functions
	int			m_RootSize;				// Firmware Size
	char		m_TTVersionAsString[16];		
	TT_VersionNumber_t m_TTVersionNumber;
	MyProgram_t	CurProg;				// Current programm
	bool		m_osdshown;
	WNDPROC		m_original_wndproc;
	HWND		m_subclass_hwnd;
	char		m_progdvb_osd_window_nr;
	bool		m_use_alternate_osd;
};

extern CAPI_Impl *g_API_Impl;
#endif
