#include "N-ScanHub.h"
#include <stdio.h>
#include <windows.h>
#include <chrono>
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <thread>
#include <ctime>

using namespace std;
bool bRecv = false;
void ReadCallback(const HANDLEDEV hDevice, const char* buf, int len, void* userParam)
{
	printf("Callback hDevice=%p,receivedDataLen=%d\nreceivedData=%s\n", hDevice, len, buf);
	bRecv = true;
}


int main(int argc, char* argv[])
{

	int deviceCounts = 0;
	HANDLEDEVLST hDeviceList = NULL;

	printf("enum nl_EnumDevices begin\n");
	//枚举设备，可以单独枚举不同连接类型的设备，根据情况进行组合
	//Enumerate devices; devices of different connection types can be enumerated separately and combined as needed
	//hDeviceList = nl_EnumDevices(&deviceCounts, ENUM_SERIALUSB);
	// hDeviceList = nl_EnumDevices(&deviceCounts, ENUM_USB);
	//hDeviceList = nl_EnumDevices(&deviceCounts, ENUM_SERIAL|ENUM_SERIALUSB|ENUM_USB);
	hDeviceList = nl_EnumDevices(&deviceCounts, ENUM_ALL);
	//hDeviceList = nl_EnumDevices(&deviceCounts, ENUM_NET);								//8
	//hDeviceList = nl_EnumDevices(&deviceCounts, ENUM_NET | ENUM_SERIAL);					//9
	//hDeviceList = nl_EnumDevices(&deviceCounts, ENUM_NET | ENUM_SERIALUSB);				//10
	//hDeviceList = nl_EnumDevices(&deviceCounts, ENUM_NET | ENUM_SERIAL | ENUM_SERIALUSB);	//11
	printf("enum nl_EnumDevices end deviceCounts=%d\n", deviceCounts);

	for (int i = 0; i < deviceCounts; i++) // Get all device information
	{
		HANDLEDEV hDevice;
		//连接设备
		//Connect to the device
		hDevice = nl_OpenDevice(hDeviceList, i); 
		printf("hDevice=%p, %s\n", hDevice, hDevice != NULL ? "succeed in opening the device" : "failed to open the device");

		if (NULL == hDevice)
			continue;

		if (argc < 2) {
			STDeviceInfo dInfo;
			memset(&dInfo, 0, sizeof(STDeviceInfo));
			//获取设备信息
			//Obtain device information
			nl_GetDeviceInfoByHandle(hDevice, &dInfo);
			printf("type=[%d] info=[%s]\n", dInfo.devType, dInfo.devInfo);
		}
		else if (argc >= 2 && strcmp(argv[1], "--SendCommand") == 0)
		{
			char buf[] = "IECREN1;IECRDT700;SOPCFGW3siZ2xvYmFsQ29uZmlnIjp7ImNvbmZpZ0FJRGVjb2RlIjp7Im91dGVyRmlsdGVyIjp7InR5cGUiOiJOb25lIn0sIm91dHB1dE9wdGlvbiI6eyJhaW1JRCI6ZmFsc2UsImJhZFJlYWRTdHJpbmciOiIiLCJjb2RlSUQiOmZhbHNlLCJkZWNvZGVUaW1lIjpmYWxzZSwibGVuZ3RoIjpmYWxzZSwib3V0cHV0UmF3Ijp0cnVlLCJwb3NpdGlvbiI6ZmFsc2UsInBwbSI6ZmFsc2UsInJvaUluZGV4IjpmYWxzZX19LCJjb25maWdDb2RlRGV0ZWN0Ijp7Im91dGVyRmlsdGVyIjp7InR5cGUiOiJOb25lIn0sIm91dHB1dE9wdGlvbiI6eyJiYWRSZWFkU3RyaW5nIjoiIn19LCJjb25maWdHZW5lcmFsT2NyIjp7Im91dGVyRmlsdGVyIjp7InR5cGUiOiJOb25lIn0sIm91dHB1dE9wdGlvbiI6eyJiYWRSZWFkU3RyaW5nIjoiIn19LCJuZWVkRnVsbFJlc3VsdCI6dHJ1ZX0sInNvcEdyb3VwIjpbeyJTZXJ2aWNlVW5pdHMiOlt7ImlkIjowLCJuYW1lIjoiTkFNRV9TRVJWSUNFX1VOSVRfR0VUX0lNRyJ9LHsiY3VzdG9tQXR0ckpzb24iOnt9LCJpZCI6MSwiaW1nUm90YXRlQW5nbGUiOjAsImluZGV4UHJlSW1nU1UiOjAsImluZGV4UHJlUGFyYW1TVSI6LTEsImluZGV4UHJlUHJvY2Vzc1BVIjotMSwiaXNPdXRwdXROb2RlIjp0cnVlLCJsaXN0Um9pSWQiOltdLCJuYW1lIjoiTkFNRV9TRVJWSUNFX1VOSVRfR0VORVJBTF9PQ1IiLCJuZWVkVXBkYXRlSW1nQ3RybCI6ZmFsc2UsInNhdmVJbnB1dEltZyI6ZmFsc2UsInNhdmVPdXRwdXRJbWciOnRydWV9XSwic29wSUQiOjEsInNvcE5hbWUiOiLmlbDlrZdPQ1Lor4bliKsifSx7IlNlcnZpY2VVbml0cyI6W3siaWQiOjAsIm5hbWUiOiJOQU1FX1NFUlZJQ0VfVU5JVF9HRVRfSU1HIn0seyJjdXN0b21BdHRySnNvbiI6e30sImlkIjoxLCJpbWdSb3RhdGVBbmdsZSI6MCwiaW5kZXhQcmVJbWdTVSI6MCwiaW5kZXhQcmVQYXJhbVNVIjotMSwiaW5kZXhQcmVQcm9jZXNzUFUiOi0xLCJpc091dHB1dE5vZGUiOmZhbHNlLCJsaXN0Um9pSWQiOltdLCJuYW1lIjoiTkFNRV9TRVJWSUNFX1VOSVRfQUlfREVURUNUX0JBUkNPREUiLCJuZWVkVXBkYXRlSW1nQ3RybCI6ZmFsc2UsInNhdmVJbnB1dEltZyI6ZmFsc2UsInNhdmVPdXRwdXRJbWciOmZhbHNlfSx7ImN1c3RvbUF0dHJKc29uIjp7ImZyYW1lTGltaXQiOjN9LCJpZCI6MiwiaW1nUm90YXRlQW5nbGUiOjAsImluZGV4UHJlSW1nU1UiOjAsImluZGV4UHJlUGFyYW1TVSI6MSwiaW5kZXhQcmVQcm9jZXNzUFUiOjEsImlzT3V0cHV0Tm9kZSI6dHJ1ZSwibGlzdFJvaUlkIjpbXSwibmFtZSI6Ik5BTUVfU0VSVklDRV9VTklUX0FJX0RFQ09ERSIsIm5lZWRVcGRhdGVJbWdDdHJsIjpmYWxzZSwic2F2ZUlucHV0SW1nIjpmYWxzZSwic2F2ZU91dHB1dEltZyI6dHJ1ZX1dLCJzb3BJRCI6MCwic29wTmFtZSI6IkFJ5p2h56CB5L2N572u5qOA5rWLK0FJ6Kej56CBIn1dLCJ0cmlnVGFnIjoxfV0=";
			T_CommunicationResult res = nl_SendCommand(hDevice, buf, strlen(buf));
			printf("res=%d\n", res);
		}
		else if (argc >= 2 && strcmp(argv[1], "--GetPictureByConfig") == 0) // Get device image
		{
			// Obtain image data with configurable parameters.
			{
				//设置监听
				//Set up monitoring
				nl_SetListener(hDevice, ReadCallback);
				//等待接收护照信息
				while (!bRecv) {
					Sleep(300);
				}
				unsigned int imgWidth = 0, imgHeight = 0;
				//获取图片分辨率
				//Obtain the image resolution
				bool isGetPicSizeOK = nl_GetPicSize(hDevice, &imgWidth, &imgHeight); // Get the image width and height
				printf("nl_GetPicSize isGetPicSizeOK=%d\n", isGetPicSizeOK);
				if (isGetPicSizeOK && imgWidth > 0 && imgHeight > 0)
				{
					printf("imgWidth=%d,imgHeight=%d\n", imgWidth, imgHeight);
					const int RECV_BUFFER_SIZE = imgWidth * imgHeight * 4;
					// Allocate a sufficiently large space to store image data
					unsigned char* recvBuffer = (unsigned char*)malloc(RECV_BUFFER_SIZE);
					STImgParam imgParam;
					memset(&imgParam, 0, sizeof(STImgParam));
					imgParam.t = 0;//参数在接口文档里有说明
					imgParam.f = 2;//推荐参数2，直接取JPG
					imgParam.q = 0;
					STImgResolution imgR[4];
					memset(imgR, 0, sizeof(STImgResolution) * 4);

					memset(recvBuffer, 0, RECV_BUFFER_SIZE);
					unsigned int nRealLen = RECV_BUFFER_SIZE;
					//获取图片内容，nRealLen传入recvBuffer的大小
					//Obtain the image content; the size of recvBuffer needs to be passed in for nRealLen
					bool isOK = nl_GetPicDataByConfig(hDevice, imgParam, recvBuffer, &nRealLen, imgR); // Get the image data
					printf("j=%d, isOK=%d， nRealLen=%d\n", j, isOK, nRealLen);

					char filename[1024] = { 0 };
					if (isOK) {
						if (imgParam.f == 1) {
							sprintf(filename, "test3%d.bmp", i);
							FILE* fp = fopen(filename, "wb");
							fwrite(recvBuffer, 1, nRealLen, fp);
							fclose(fp);
						}
						else if (imgParam.f == 2) {
							sprintf(filename, "./pic/test4%d%06d.jpg", i, j);
							FILE* fp = fopen(filename, "wb");
							fwrite(recvBuffer, 1, nRealLen, fp);
							fclose(fp);
						}
						else if (imgParam.f == 3) {
							sprintf(filename, "test5%d.tiff", i);
							FILE* fp = fopen(filename, "wb");
							fwrite(recvBuffer, 1, nRealLen, fp);
							fclose(fp);
						}
						else if (imgParam.f == 4) {
							sprintf(filename, "test6%d.bmp", i);
							FILE* fp = fopen(filename, "wb");
							fwrite(recvBuffer, 1, nRealLen, fp);
							fclose(fp);
						}
						else if (imgParam.f == 0) {
							long outLen = 0;
							STImgResolution imgResIn, imgResOut;
							imgResIn.width = imgWidth;
							imgResIn.height = imgHeight;
							unsigned int imgLen = 0;
							//获取图片色彩类型
							//Obtain the image color type
							IMG_TYPE type = nl_GetDeviceImageColorType(hDevice, &imgResOut, &imgLen);
							//彩色图片
							//Color image
							if (type == TYPE_COLOR) {
								unsigned char* outBuf = (unsigned char*)malloc(imgLen);
								printf("imgLen=%d\n", imgLen);
								//色彩空间转换
								//Color space conversion
								bool res = nl_ConvertImageColorSpace(hDevice, recvBuffer, RECV_BUFFER_SIZE, imgResIn, outBuf);
								int oWidth, oHeight;
								if (strlen(imgParam.b) != 0) {
									oWidth = stoi(string(imgParam.b).substr(8, 4));
									oHeight = stoi(string(imgParam.b).substr(12, 4));
								}
								else {
									oWidth = imgResOut.width;
									oHeight = imgResOut.height;
								}
								//保存图片，最后一个参数说明详见接口文档
								//Save the image; for the description of the last parameter, please refer to the interface documentation
								sprintf(filename, "./pic/test2%d.bmp", j);
								nl_SavePicDataToFile(filename, outBuf, oWidth, oHeight, 24); // Save image
								sprintf(filename, "./pic/test2%d.jpg", j);
								nl_SavePicDataToFile(filename, outBuf, oWidth, oHeight, 23); // Save image
							}
							else {
								int oWidth, oHeight;
								if (strlen(imgParam.b) != 0) {
									oWidth = stoi(string(imgParam.b).substr(8, 4));
									oHeight = stoi(string(imgParam.b).substr(12, 4));
								}
								else {
									oWidth = imgResOut.width;
									oHeight = imgResOut.height;
								}
								sprintf(filename, "./pic/test1%d.bmp", j);
								nl_SavePicDataToFile(filename, recvBuffer, oWidth, oHeight, 8); // Save image
								sprintf(filename, "./pic/test1%d.jpg", j);
								nl_SavePicDataToFile(filename, recvBuffer, oWidth, oHeight, 13); // Save image
							}
						}
					}

					free(recvBuffer);
					recvBuffer = NULL;
					if (!isOK)
						break;
				}
			}
		}
		bool isClosed = nl_CloseDevice(&hDevice); // Close the device
		printf("hDevice=%p,%s\n", hDevice, isClosed ? "succeed in closing the device" : "failed to close the device");
	}
	nl_ReleaseDevices(&hDeviceList); // Release the device list handle

	printf("all over\n");

	system("pause");


	return 0;
}