/*
 * Emunation Plugin for MD-API 
 *
 * This code is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This code 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 */
 
#ifndef _DLL_H_
#define _DLL_H_


#include "API_Impl.h"
#include "resource.h"
#include "logger.h"

#define DEBUG_PLG
#define ECM_FILTER_ID 0x1001
#define ECM_FILTER_NAME "EmuNation ECM Filter"

#define EMM_FILTER_ID 0x1002
#define DATA_FILTER_ID 0x1003
#define EMM_FILTER_NAME "EmuNation EMM Filter"

#include "system.h"

//Parsing DVB Data Information
#include ".\\dvbparser\\dvbparser.h"
#include <queue>

#define MSG_INFO 0x001
#define MSG_MESSAGE 0x002
#define MSG_ECM 0x003
#define MSG_KEY 0x004
#define MSG_DATAFLOW 0x005
#define MSG_BUFINFO 0x006
#define MSG_PIDINFO 0x007

#define EVENT_IDLE   0x001
//Stop Filter Events
#define EVENT_STOPPMTFILTER 0x002
#define EVENT_STOPECMFILTER 0x003
#define EVENT_STOPEMMFILTER 0x004
//Start Filter Events
#define EVENT_STARTPMTFILTER 0x005
#define EVENT_STARTECMFILTER 0x006
#define EVENT_STARTEMMFILTER 0x007

typedef struct _FILTERDATA
{
    int FilterID;
    unsigned char Data[188];
}FILTERDATA;
void DATA_FLOW(void* impl);

class DllClass:public CAPI_Impl
{
  public:
    DllClass();
    virtual ~DllClass(void);
    virtual BOOL DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved);
    virtual void On_Send_Dll_ID_Name(char *Name);
  	void On_Menu_Select(unsigned int MenuID );
	void On_Hot_Key();
	void On_Start(HINSTANCE MDInstance, HWND MDWnd, BOOL Log_Set, int DLL_ID, char *My_Hot_Key,char *Api_Version, int *Keep_me_running );
	void On_Channel_Change( const struct TProgramm82 &CurrentProgramm );
    void On_Filter_Data_Arrival(int MyFilter, int DataLen, unsigned char *_Data);
    void On_Filter_Close(unsigned int FilterOffset );
    void On_Exit(HINSTANCE MDInstance, HWND MDWnd, BOOL Log_Set);
    void ShowDialog(int);
    void to_log(char *x);
    void to_binlog(char* filename,unsigned char* data,int length);
    int Start_Filter(struct TSTART_FILTER *sf);
    int Stop_Filter(int filterid);

    void OnDVBCoreInit(HWND Handle);
    void OnEmunationInit();
    bool DVBCoreFlag;
    HINSTANCE GetDLLInstance();
    bool GetState();
    void Log(const char* format,...);
    void FoundKey();
    void Turn(int count);
    void SaveKey(char type,int keyid,int keynr,unsigned char* key,int keylen,unsigned char* oldkey);
    void On_Channel_Change_TH( const struct TProgramm82 &CurrentProgramm );
    bool IsChChanged;
    TSTART_FILTER m_ecmfilter;
    TSTART_FILTER m_emmfilter;
    TSTART_FILTER m_datafilter;

    cSystem* m_cursys;
    bool PushMessage(int msgtype,char* msg); 
    unsigned char* m_prevecmdata;

    //Filter Control
    bool StopECMFilter();
    bool StartECMFilter(TProgramm82* CurrentProgramm);
    bool StopEMMFilter();
    bool StartEMMFilter(TProgramm82* CurrentProgramm);
    bool StopDataFilter();
    bool StartDataFilter();
    //DVBCore Filter Control
    bool DVBCORE_Start_Filter(struct TSTART_FILTER *sf);
    bool DVBCORE_Stop_Filter(int flt_id);
    //Filter thread signalled
    bool StopECMFilter_TH();
    bool StartECMFilter_TH(TProgramm82* CurrentProgramm);
    bool StopEMMFilter_TH();
    bool StartEMMFilter_TH(TProgramm82* CurrentProgramm);
    bool StopDataFilter_TH();    
    bool StartDataFilter_TH();

    
    bool m_isecmfilter;
    bool m_isemmfilter;
    bool m_ispmtfilter;

    HWND m_hwnd_console;
    char m_infotext[60];
    char m_keystr[60];
    char m_ecmtext[184*3+1];
    TProgramm82 m_curprg;
    void InitializeOptions();
    void SaveOptions();
    bool IsCWNecessary(unsigned char* _Data);
    void WriteECM(unsigned char* _Data);
    bool ProcessPMT(unsigned char* _Data,int DataLen);
    void SendDCW(unsigned char* cw);

    int PluginEvent;
    bool SignalStopFilter (int type);
    bool SignalStartFilter (int type);
    std::queue<FILTERDATA> m_ECMq;
    std::queue<FILTERDATA> m_EMMq;
    std::queue<FILTERDATA> m_PMTq;

    std::queue<int> m_FilterEvents;
    void ProcessECMData(FILTERDATA* fltdata);
    void ProcessEMMData(FILTERDATA* fltdata);
    void ProcessPMTData(FILTERDATA* fltdata);
    void UpdatePIDInfo(int FilterID);
    void ClearAllData();
    bool m_pmtok;
    bool m_clearevent;
    bool m_clearfilter_event;
    void InitializeMenu();
    bool ThreadState;
    bool IsInitialized;
  private:
    bool m_plg_active;
    bool m_isautoecm;
    int m_flow;
    int m_curecmindex;
    int m_emmcount;
    bool m_readpmt;

#ifdef PMT_PROCESSING
    cDVBParser m_dvbp;
    cLogger m_logger;
    char INI_FILE [_MAX_PATH];
#endif

};
extern DllClass m_DLLInstance;


#endif /* _DLL_H_ */
