#include "pch.h"
#include <stdio.h>

#include "ComPortTools.h"

#include <setupapi.h>
#include <devguid.h>
#pragma comment(lib,"SetupAPI.lib")

void COM_InitPortList(std::vector<sComPort>& ports, const wchar_t* name = L"")
{
	ports.clear();
	HDEVINFO hDevInfo;
	SP_DEVINFO_DATA DeviceInfoData;
#ifdef UNICODE
	wchar_t buf[256];
#else
	char buf[256];
#endif
	int i;
	int defaultComId = -1;

	// Create a HDEVINFO of all Ports device class 
	hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS,
		0, // Enumerator
		0,
		DIGCF_PRESENT | DIGCF_PROFILE);
	//	DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

	if (hDevInfo == INVALID_HANDLE_VALUE)
	{
		// Insert error handling here.
		return;
	}
	// Enumerate through all devices in Set.
	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	CString str, subStr;
	int index1, index2;
	sComPort port;
	for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++)
	{
		SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)buf, sizeof(buf), NULL);
		str = buf;
		if (name && wcslen(name)) {
			if (str.Find(name) < 0) continue;
		}
		index1 = str.Find(_T("(COM"), 0);
		index2 = str.Find(_T(")"), index1);
		subStr = str.Mid(index1 + 1, index2 - index1 - 1);
#ifdef UNICODE
		port.port = _wtoi(subStr.GetBuffer(subStr.GetLength()) + 3);
#else
		port.port = atoi(subStr.GetBuffer(subStr.GetLength()) + 3);
#endif
		port.portName = str;
		ports.push_back(port);
	}

	SetupDiDestroyDeviceInfoList(hDevInfo);
}

#ifdef _AFXDLL
void COM_PortListToCombo(const std::vector<sComPort>& ports, CComboBox* Box, int defaultCom)
{
	int i;
	int defaultComId = -1;

	int index;
	for (i = 0; i<ports.size(); i++)
	{
		index = Box->AddString(ports[i].portName.c_str());

		Box->SetItemData(index, ports[i].port);
		if (defaultCom == ports[i].port) defaultComId = index;
	}
	if (ports.size() > 0) {
		if (defaultComId >= 0)
		{
			Box->SetCurSel(defaultComId);
		}
		else
		{
			Box->SetCurSel(0);
		}

	}

	return;
}

void COM_RefreshPortList(const wchar_t* name, CComboBox* Box)
{
	int lastport = int(Box->GetItemData(Box->GetCurSel()));
	Box->ResetContent();
	std::vector<sComPort> ports;
	COM_InitPortList(ports, name);
	
	if (ports.size() > 0) {
		COM_PortListToCombo(ports, Box, 0);
		int i;
		for (i = 0; i < Box->GetCount(); i++) {
			if (lastport == Box->GetItemData(i)) {
				Box->SetCurSel(i);
				break;
			}
		}
		if (i == Box->GetCount()) {
			Box->SetCurSel(0);
		}
	}
}

int COM_GetSelectedPort(CComboBox* Box)
{
	int index = Box->GetCurSel();
	if (index >= 0) {
		return int(Box->GetItemData(index));
	}
	else {
		return 0;
	}
}

//CComboBox必须sort属性=false
void COM_InitBaudList(const int* List, int Num, int default_val, CComboBox* Box)
{
	int i, index;
	int default_id = 0;
	TCHAR buf[10];
	for (i = 0; i < Num; i++) {
		_itot_s(List[i], buf, 10, 10);

		index = Box->AddString(buf);
		Box->SetItemData(index, List[i]);
		if (default_val == List[i])
			default_id = i;
	}
	Box->SetCurSel(default_id);
}

void COM_InitBaudList(const std::vector<uint32_t>& List, int default_val, CComboBox* Box)
{
	int i, index;
	int default_id = 0;
	TCHAR buf[10];
	for (i = 0; i < List.size(); i++) {
		_itot_s(List[i], buf, 10, 10);

		index = Box->AddString(buf);
		Box->SetItemData(index, List[i]);
		if (default_val == List[i])
			default_id = i;
	}
	Box->SetCurSel(default_id);
}
#endif