#pragma once



class CBaseReader;
class CRSCTCriticalSection;

#include "cjeca32.h"

#ifdef _MAC
# define CREADER_CLASS_EXPORT
#else
	#ifdef WIN_UMDF
	#include "umdf.h"
	#endif
	# define CREADER_CLASS_EXPORT  CJECA32_API
#endif

class CREADER_CLASS_EXPORT CReader
{
public:
#ifdef WIN_UMDF
	CReader(UMDF_CALLBACK* p_pcUmdfCallBack);
#endif
	CReader(char *cDeviceName);
	CReader(const char *cDeviceName);
	virtual ~CReader(void);
	CJ_RESULT Connect();
    CJ_RESULT CreateVirtualReaderObject(const char *cReaderName);
	CJ_RESULT Disonnect();
private:
	void CReaderConstructor(const char *cDeviceName);

public:
	char CtData(RSCT_UINT8 *dad,RSCT_UINT8 *sad, RSCT_UINT16 cmd_len, const RSCT_UINT8 *cmd, RSCT_UINT16 *response_len, RSCT_UINT8 *response);

public:
	RSCT_IFD_RESULT IfdPower(RSCT_UINT32 Mode,RSCT_UINT8 *ATR,RSCT_UINT32 *ATR_Length);
	RSCT_IFD_RESULT IfdSetProtocol(RSCT_UINT32 *Protocol);
	RSCT_IFD_RESULT IfdGetState(RSCT_UINT32 *State);
	RSCT_IFD_RESULT IfdSetAttribute(const RSCT_UINT8 *Input,RSCT_UINT32 InputLength);
	RSCT_IFD_RESULT IfdGetAttribute(RSCT_UINT32 Tag,RSCT_UINT8 *Attribute,RSCT_UINT32 *AttributeLength);
	RSCT_IFD_RESULT IfdSwallow();
	RSCT_IFD_RESULT IfdEject();
	RSCT_IFD_RESULT IfdVendor(RSCT_UINT32 IoCtrlCode,RSCT_UINT8 *Input,RSCT_UINT32 InputLength,RSCT_UINT8 *Output,RSCT_UINT32 *OutputLength);
	RSCT_IFD_RESULT IfdTransmit(const RSCT_UINT8 *cmd, RSCT_UINT16 cmd_len,RSCT_UINT8 *response,RSCT_UINT16 *response_len);
	RSCT_IFD_RESULT IfdIoControl(RSCT_UINT32 IoCtrlCode,RSCT_UINT8 *Input,RSCT_UINT32 InputLength,RSCT_UINT8 *Output,RSCT_UINT32 *OutputLength);

	
public:
	CJ_RESULT CtLoadModule(RSCT_UINT8 *pData,RSCT_UINT32 DataLength,RSCT_UINT8 *pSgn,RSCT_UINT32 SgnLength,RSCT_UINT32 *Result);
	CJ_RESULT CtKeyUpdate(RSCT_UINT8 *pData,RSCT_UINT32 DataLength,RSCT_UINT32 *Result);
	CJ_RESULT CtIsKeyUpdateRecommended(RSCT_UINT8 *pData,RSCT_UINT32 DataLength,RSCT_UINT32 *EstimatedUpdateTime);
	CJ_RESULT CtDeleteModule(RSCT_UINT32 ModuleID,RSCT_UINT32 *Result);
	CJ_RESULT CtActivateModule(RSCT_UINT32 ModuleID,RSCT_UINT32 *Result);
	CJ_RESULT CtDeactivateModule(RSCT_UINT32 ModuleID,RSCT_UINT32 *Result);
	CJ_RESULT CtDeleteALLModules(RSCT_UINT32 *Result);
	CJ_RESULT CtListModules(RSCT_UINT32 *Count,cj_ModuleInfo *ModuleInfo);
	CJ_RESULT CtGetModuleInfoFromFile(RSCT_UINT8 *pData,RSCT_UINT32 DataLength,cj_ModuleInfo *ModuleInfo,RSCT_UINT32 *EstimatedUpdateTime);
	CJ_RESULT CtFreeModuleInfoList(cj_ModuleInfo *pModuleInfo);
	CJ_RESULT CtIsModuleUpdateRecommended(RSCT_UINT8 *pData,RSCT_UINT32 DataLength,RSCT_UINT32 *EstimatedUpdateTime);
	CJ_RESULT CtGetActiveModuleID(RSCT_UINT32 *ID,RSCT_UINT32 *Result);
	CJ_RESULT CtGetActivationID(RSCT_UINT32 *ID,RSCT_UINT32 *Result);
	CJ_RESULT CtApplicationData(RSCT_UINT32 ApplicationID,RSCT_UINT16 Function,RSCT_UINT8 *InputData, RSCT_UINT32 InputLen, RSCT_UINT32 *Result, RSCT_UINT8 *ResponseData, RSCT_UINT32 *ResponseLen);
	CJ_RESULT CtApplicationDataEx(RSCT_UINT32 ApplicationID,RSCT_UINT16 Function,RSCT_UINT8 *InputData, RSCT_UINT32 InputLen, RSCT_UINT32 *Result, RSCT_UINT8 *ResponseData, RSCT_UINT32 *ResponseLen, RSCT_UINT8 *ApplicationError,RSCT_UINT32 *ApplicationErrorLength);
	CJ_RESULT CtSelfTest(void);
	CJ_RESULT CtSelfTest2(const RSCT_UINT8 *TransportKey,RSCT_UINT8 KeyNr);
	CJ_RESULT CtShowAuth(void);
	CJ_RESULT CtSetAPDUNorm(const EApduNorm Norm);
	CJ_RESULT CtSetContrast(EContrast eContrast,RSCT_UINT32 *Result);
	CJ_RESULT CtSetBacklight(EBacklight eBacklight,RSCT_UINT32 *Result);
	CJ_RESULT CtSetSilentMode(bool boolMode,bool *pboolMode,RSCT_UINT32 *Result);
	CJ_RESULT CtGetSilentMode(bool *pboolMode,RSCT_UINT32 *Result);
	CJ_RESULT CtSetModulestoreInfo(RSCT_UINT8 *Info,RSCT_UINT8 InfoLength);
	CJ_RESULT CtGetModulestoreInfo(RSCT_UINT8 *Info,RSCT_UINT8 *InfoLength);

	CJ_RESULT CtSetMFT(const RSCT_UINT8 *const pData, RSCT_UINT32 DataLen, RSCT_UINT32 *Result);
	CJ_RESULT CtGetMFT(cj_MFT_Info *const pData, RSCT_UINT32 *const pNumElemnts);
	
	CJ_RESULT InstallAndStartIFDHandler();
	CJ_RESULT StopIFDHandler();
	CJ_RESULT IntroduceReaderGroups();



	CJ_RESULT CtGetReaderInfo(cj_ReaderInfo *pReaderInfo);

public:
	void SetChangeInterruptCallback(fctChangeIntCallback ChangeIntCallback,ctxPtr ChangeOwner);
	void SetKeyInterruptCallback(fctKeyIntCallback KeyIntCallback,ctxPtr KeyOwner);

	void DebugResult(const char *format, ...);
	void DebugErrorSW1SW2(const char *format, ...);
	void DebugLeveled(RSCT_UINT32 Mask,const char *format, ...);
	CRSCTCriticalSection *CritSec;

private:
	CBaseReader *m_Reader;
	void CheckcJResult(CJ_RESULT Result);
	char *m_cDeviceName;

public:

#ifdef D_DOUBLE_DECORADED
public:
	RSCT_IFD_RESULT2 IfdPower(uint32_t Mode, uint8_t *ATR, uint32_t *ATR_Length);
	RSCT_IFD_RESULT2 IfdSetProtocol(uint32_t *Protocol);
	RSCT_IFD_RESULT2 IfdGetState(uint32_t *State);
	RSCT_IFD_RESULT2 IfdSetAttribute(const uint8_t *Input, uint32_t InputLength);
	RSCT_IFD_RESULT2 IfdGetAttribute(uint32_t Tag, uint8_t *Attribute, uint32_t *AttributeLength);
	RSCT_IFD_RESULT2 IfdVendor(uint32_t IoCtrlCode, uint8_t *Input, uint32_t InputLength, uint8_t *Output, uint32_t *OutputLength);
//	RSCT_IFD_RESULT2 IfdTransmit(const uint8_t *cmd, uint16_t cmd_len, uint8_t *response, uint16_t *response_len);
	RSCT_IFD_RESULT2 IfdIoControl(uint32_t IoCtrlCode, uint8_t *Input, uint32_t InputLength, uint8_t *Output, uint32_t *OutputLength);
public:
	CJ_RESULT CtLoadModule(uint8_t *pData, uint32_t DataLength, uint8_t *pSgn, uint32_t SgnLength, uint32_t *Result);
	CJ_RESULT CtKeyUpdate(uint8_t *pData, uint32_t DataLength, uint32_t *Result);
	CJ_RESULT CtIsKeyUpdateRecommended(uint8_t *pData, uint32_t DataLength, uint32_t *EstimatedUpdateTime);
	CJ_RESULT CtDeleteModule(uint32_t ModuleID, uint32_t *Result);
	CJ_RESULT CtActivateModule(uint32_t ModuleID, uint32_t *Result);
	CJ_RESULT CtDeactivateModule(uint32_t ModuleID, uint32_t *Result);
	CJ_RESULT CtDeleteALLModules(uint32_t *Result);
	CJ_RESULT CtListModules(uint32_t *Count, cj_ModuleInfo *ModuleInfo);
	CJ_RESULT CtGetModuleInfoFromFile(uint8_t *pData, uint32_t DataLength, cj_ModuleInfo *ModuleInfo, uint32_t *EstimatedUpdateTime);
	CJ_RESULT CtIsModuleUpdateRecommended(uint8_t *pData, uint32_t DataLength, uint32_t *EstimatedUpdateTime);
	CJ_RESULT CtGetActiveModuleID(uint32_t *ID, uint32_t *Result);
	CJ_RESULT CtGetActivationID(uint32_t *ID, uint32_t *Result);
	CJ_RESULT CtApplicationData(uint32_t ApplicationID, uint16_t Function, uint8_t *InputData, uint32_t InputLen, uint32_t *Result, uint8_t *ResponseData, uint32_t *ResponseLen);
	CJ_RESULT CtApplicationDataEx(uint32_t ApplicationID, uint16_t Function, uint8_t *InputData, uint32_t InputLen, uint32_t *Result, uint8_t *ResponseData, uint32_t *ResponseLen, uint8_t *ApplicationError, uint32_t *ApplicationErrorLength);
//	CJ_RESULT CtSelfTest2(const uint8_t *TransportKey, uint8_t KeyNr);
	CJ_RESULT CtSetContrast(EContrast eContrast, uint32_t *Result);
	CJ_RESULT CtSetBacklight(EBacklight eBacklight, uint32_t *Result);
	CJ_RESULT CtSetSilentMode(bool boolMode, bool *pboolMode, uint32_t *Result);
	CJ_RESULT CtGetSilentMode(bool *pboolMode, uint32_t *Result);
	CJ_RESULT CtSetMFT(const uint8_t *const pData, uint32_t DataLen, uint32_t *Result);
	CJ_RESULT CtGetMFT(cj_MFT_Info *const pData, uint32_t *const pNumElemnts);
	//	CJ_RESULT CtSetModulestoreInfo(uint8_t *Info, uint8_t InfoLength);
//	CJ_RESULT CtGetModulestoreInfo(uint8_t *Info, uint8_t *InfoLength);
public:
	void DebugLeveled(uint32_t Mask, const char *format, ...);
#endif

};

