#ifndef Z_INTERFACE_H
#define Z_INTERFACE_H

#include "SimpleGXCREF_OuterEnum.h"
#include "SimpleGXCREF_type.h"

#define DLL_EXPORT  __declspec(dllexport)






/// <summary>
/// Simple MX
/// </summary>
class DLL_EXPORT MX
{
private:
	char* IPAddress;
	QBYTE CPUType;
	char CPUName[15];

	QWORD Port = 0;
	QWLONG sock = 0;
	QWORD global_cnt = 0;
	MC_Setting param;


	void CommonInit(QBYTE MCProtocol, char* IPAddress);
	void ParamSet();

public:
	QBYTE identify[2] = { 0xAA,0xBB };
	QBYTE ActSourceUnitNumber = 0x00;
	QBYTE ActNetworkNumber = 0x00;
	QBYTE ActUnitNumber = 0xFF;
	QWORD ActIONumber = 0x03FF;
	QBYTE ActConnectUnitNumber = 0x00;
	QBYTE ActSourceStation = 0x00;
	QWORD CPUTimer = 0x1000;
	QBYTE isBinary = (char)enumIsBinary::True;
	QBYTE QiQ = (char)enumPLC::Q;
	QBYTE Frame = (char)enumMCFrame::C2;
	QBYTE Protocol = (char)enumMCProtocol::GXSim2;



	~MX() noexcept;


	/// <summary>GX Simulator2 用コンストラクタ</summary>
	MX(char CPUType, QBYTE MCProtocol);

	/// <summary>MCプロトコル(3E, 4E) 用コンストラクタ</summary>
	MX(char* IPAddress, QWORD IPPort, QBYTE MCProtocol, QBYTE QiQ);  

	/// <summary>受信タイムアウト</summary>
	QWORD  TimeoutSec = 1;

	
	int getCPUName(char* cpuName);


	/// <summary>ソケットオープン</summary>
	QWLONG SockOpen();

	/// <summary>ソケットクローズ</summary>
	int SockClose();

	/// <summary>ソケットクローズ</summary>
	int SockClose(int sock);


	/// <summary>メモリ解放</summary>
	void MX::freeRcv(RcvWORD* p);

	///////////

/// <summary>デバイスのデータを読み込む</summary>
/// <param name="dev"> dev[0]="D0", dev[1]="D1"... といった配列 でデバイス番号群を指定</param>
/// <param name="figs">点数を指定</param>
/// <param name="dat"> 読込データ</param>
/// <returns>可否</returns>
	int ReadDeviceRandom(char* dev[], QWORD words, QWORD* dat);


/// <summary>デバイスのデータを読み込む</summary>
/// <param name="dev">"D0\nD3..." でデバイス番号群を指定</param>
/// <param name="figs">点数を指定</param>
/// <returns>可否</returns>
	int ReadDeviceRandom(char* dev, QWORD words, QWORD* dat);


	/// <summary>デバイスにデータを書き込む</summary>
/// <param name="dev"> dev[0]="D0", dev[1]="D1"... といった配列 でデバイス番号群を指定</param>
/// <param name="figs">点数を指定</param>
/// <param name="dat"> 書込データ</param>
/// <returns>可否</returns>
	int WriteDeviceRandom(char* dev[], QWORD words, QWORD* dat);


	/// <summary>デバイスにデータを書き込む</summary>
/// <param name="dev">"D0\nD3..." でデバイス番号群を指定</param>
/// <param name="figs">点数を指定</param>
/// <param name="dat"> 書込データ</param>
/// <returns>可否</returns>
	int WriteDeviceRandom(char* dev, QWORD words, QWORD* dat);



	/// <summary>デバイスのデータを読み込む</summary>
	/// <param name="dev">"D0" で最初のデバイス番号を指定</param>
	/// <param name="figs">点数を指定</param>
	/// <param name="dat"> 読込データ</param>
	/// <returns>可否</returns>
	int ReadDeviceBlock(char* dev, QWORD words, QWORD* dat);

	/// <summary>デバイスにデータを書込む</summary>
/// <param name="dev">"D0" で最初のデバイス番号を指定</param>
/// <param name="figs">点数を指定</param>
/// <param name="dat"> 書込データ</param>
/// <returns>可否</returns>
	int WriteDeviceBlock(char* dev, QWORD words, QWORD* dat);


	int WriteBitDeviceBlock(char* dev, QWORD words, QWORD* dat);
	int ReadBitDeviceBlock(char* dev, QWORD words, QWORD* dat);

	int WriteBitDeviceRandom(char* dev, QWORD words, QWORD* dat);
	int WriteBitDeviceRandom(char* dev[], QWORD words, QWORD* dat);

	/* 存在せず
	int ReadBitDeviceRandom(char* dev, QWORD words, QWORD* dat);
	int ReadBitDeviceRandom(char* dev[], QWORD words, QWORD* dat);
	*/


/// <summary>バッファメモリを読み込む (GX Simulator3 では使用不可)</summary>
/// <param name="IONo">先頭 IONo(/0x10) </param>
/// <param name="IOAdd">先頭アドレス </param>
/// <param name="words">ワード数を指定</param>
/// <param name="dat"> 読込データ</param>
/// <returns>可否</returns>
    int ReadBuffer(QWORD IONo, QWORD IOAdd, QWORD words, QWORD* dat);


	/// <summary>バッファメモリを書込む (GX Simulator3 では使用不可)</summary>
/// <param name="IONo">先頭 IONo(/0x10) </param>
/// <param name="IOAdd">先頭アドレス </param>
/// <param name="words">ワード数を指定</param>
/// <param name="dat">書込データ</param>
/// <returns>可否</returns>
    int WriteBuffer(QWORD IONo, QWORD IOAdd, QWORD words, QWORD * dat);




	/// <summary>デバイス1点を読み込む</summary>
/// <param name="dev"> "D0"でデバイス番号を指定</param>
/// <param name="dat">読込データ</param>
/// <returns>可否</returns>
	int GetDevice(char* dev, QWORD &dat);


	/// <summary>デバイス1点にデータを書き込む</summary>
/// <param name="dev"> "D0"でデバイス番号を指定</param>
/// <param name="dat"> 書込データ</param>
/// <returns>可否</returns>
	int SetDevice(char* dev, QWORD dat);






};








#endif