#pragma once
#include "json.hpp"
using json = nlohmann::json;
using namespace std;

#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
	typedef unsigned char   uint8;
	typedef unsigned short  uint16;
	typedef unsigned long long uint64;

	typedef unsigned char   u8;
	typedef unsigned short  u16;
	typedef unsigned long   u32;
	typedef unsigned long long u64;

	typedef signed char   int8;
	typedef signed short  int16;
	typedef signed long long int64;

	const unsigned short vid = 4292;  //10C4
	const unsigned short pid = 60048; //EA90

#endif
	/* ***********************
	TCA9535 Configuration
	*********************** */
#define TCA9535_Intput_Port_0			0
#define TCA9535_Intput_Port_1			1
#define TCA9535_Output_Port_0			2
#define TCA9535_Output_Port_1			3
#define TCA9535_Configuration_Port_0	6
#define TCA9535_Configuration_Port_1	7
	HANDLE PrepareTCA9535(int address, int deviceIndex, int port);

	//void ReadTCA9535ConfigPort(HANDLE handle, int index);

	/* ******************
	FT260 Function
	****************** */
#define NO_DEVICE -4
#define SET_DEVICE_FAIL -5
#define SET_DEVICE_OK 0

#define MODE_232	0x3
#define MODE_485	0x8
#define MODE_422	0x4

	bool IsFT260Dev(WCHAR* devPath);
	HANDLE OpenFT260(int deviceIndex);
	void CloseFT260(HANDLE handle);
	BOOL ReadFT260Registry(HANDLE handle, uint8 address, uint8 registry, uint8* value);
	BOOL WriteFT260Registry(HANDLE handle, uint8 address, uint8 registry, uint8 value);
	int SetFT260UartMode(int address, int deviceIndex, int port, int mode);
	int GetFT260UartMode(int address, int deviceIndex, int port);


	/*********************************/
	/*  CP2112 Function              */
	/*  CP2112 to TCA9535 Function   */
	/*********************************/

	BOOL OpenCP2112(int cp2112Index);
	void CloseCP2112(void* handle);
	HANDLE PrepareCP2112_TCA9535_Bit(int cp2112Index, uint8 tcaAddr, uint8 tcaPort, int bit, uint8 mode);
	BOOL WriteCP2112Registry(void* handle, uint8 address, uint8 registry, uint8 value);
	BOOL ReadCP2112Registry(void* handle, uint8 address, uint8 registry, uint8* value);
	int SetCP2112UartMode(int interfaceAddress, int interfaceIndex, int tca9535PortIndex, int physicalPortIndex, int mode);
	int GetCP2112UartMode(int interfaceAddress, int interfaceIndex, int tca9535PortIndex, int physicalPortIndex);
	int SetCP2112Dout(int address, int deviceIndex, int port, int bit, int mode);
	int GetCP2112Din(int address, int deviceIndex, int port, int bit);
	int GetCP2112Dout(int address, int deviceIndex, int port, int bit);
	BOOL OpenCP2112_GPIO(int cp2112Index);
	HANDLE SetCP2112GpioConfig(int cp2112Index, int bit, int data_type);
	int SetCP2112GpioStatus(int cp2112Index, int gpio_bit, int data_type, int status);
	int GetCP2112GpioStatus(int cp2112Index, int gpio_bit, int data_type);
	int SetCP2112GpioDout(int cp2112Index, int gpio_bit, int status);
	int GetCP2112GpioDin(int cp2112Index, int gpio_bit);
	int GetCP2112GpioDout(int cp2112Index, int gpio_bit);
	int GetTCA9535Registry(int cp2112Index, int address, int port, int bit, int IObit);
	int SetTCA9535Registry(int cp2112Index, int address, int port, int bit, int mode, int IObit);
	int GetCP2112Tca9535Registry(int cp2112Index, int address, int port, int bit, int IOType);
	int GetCP2112Tca9535Config(int cp2112Index, int address, int port);
	int SetCP2112Tca9535Registry(int cp2112Index, int address, int port, int bit, int value);
	int SetCP2112Tca9535Config(int cp2112Index, int address, int port, uint8 mask, uint8 IOConfig);
	int SetCP2112Tca9535RegistryByPort(int cp2112Index, int address, int port, uint8 mask, uint8 value);


	// SMBus to TCA9535 function
	BOOL SetSMBusTCA9535Config(int address, int port, UINT8 mask, UINT8 config);
	int GetSMBusTCA9535Config(int address, int port);
	int SetSMBusTca9535GpioByPort(int address, int port, UINT8 mask, UINT8 value);
	UINT32 mxsmbus_open();
	void mxsmbus_close(UINT32 smbus_base_addr);
	int FindSMBusLocation(int* busNum, int* deviceNum, int* functionNum);
	int SMBusReadByte(UINT32 smbus_base_addr, UINT8 Address, UINT8 Offset, UINT8* Data);
	int SMBusWriteByte(UINT32 smbus_base_addr, UINT8 Address, UINT8 Offset, UINT8* Data);
	int PciRead(UINT8 Bus, UINT8 Dev, UINT8 Func, UINT8 Reg, UINT8 Size, VOID* Data);
	int GetSMBusTCA9535GpioStatus(int address, int port, int bit, int data_type);
	int SetSMBusTCA9535GpioStatus(int address, int port, int bit, int mode);
	int GetSMBusTCA9535GpioOutStatus(int address, int port, int bit);
	int GetSMBusTCA9535GpioInStatus(int address, int port, int bit);
	int SetSMBusTCA9535GpioOutStatus(int address, int port, int bit, int mode);

	// SMBus to EEPROM function
	int GetSMBusEEPROMBoardIndex(int address);
	//int GetSMBusEEPROMPcbaVersion(int address);
	int GetSMBusEEPROMData(int address, UINT8 offset);
	bool CheckBoardConfigBySMBusEeprom(const char* jsonObject);


#ifdef __cplusplus    // If used by C++ code, 
}
#endif