#include "stdafx.h"
#include "EpdBaseClr.h"
#pragma managed

EpdBaseClr::Epd2::Epd2(int port)
{
	//HANDLE hMod = LoadLibrary(L"Reader2.dll");
	EpdID = 0;
	isMK3 = EPDIssued = isBG = 0;
	epd = new EpdBase::Epd2U(port);
	epd3 = new Epd3Base::Epd3U(port);
	this->InitRV = epd->InitRv;
	Hp10Name = gcnew String(tHp10);
	Hp07Name = gcnew String(tHp07);
	isTitleNG = false;
}
EpdBaseClr::Epd2::~Epd2()
{
	if (epd != nullptr) {
		epd->EndCom();
		delete epd; 
		epd = nullptr;
	}
	if (epd3 != nullptr) {
		epd3->EndCom();
		delete epd3;
		epd3 = nullptr;
	}
	this->!Epd2();
}
EpdBaseClr::Epd2::!Epd2()
{
}
int EpdBaseClr::Epd2::SetFeedbackSound(byte sound, UINT16 sound3)
{
	epd->EndSessionControl = sound;
	epd3->EndSessionControl = sound3;
	return 0;
}
/// <summary>
/// find Epd
/// </summary>
/// <param name="reinit"></param>
/// <returns>0 = success </returns>
int EpdBaseClr::Epd2::Connect(bool reinit, int EPDTimeout)
{
	int rv = 1;
	ConnectError = 0;
	EpdID= 0;
	DeviceCount = 0;
	DiscRV = 0;
	if (epd != nullptr) {
		if (epd->CommsInitialized == 0) epd->StartCom();
		DiscRV = epd->StartDiscover(EPDTimeout);
		if (DiscRV == 1)
		{
			DeviceCount = epd->DeviceCount;
			if (epd->DeviceCount > 0) { 
				EpdID = epd->DeviceIDs[0]; rv = 0; 
			}
			else rv = 1;
		}
		else {
			rv = 2;
			ConnectError = epd->Error;
		}
	}
	return rv;
}
int EpdBaseClr::Epd2::Close()
{
	EpdID= 0;
	if (epd !=nullptr) 
		epd->EndCom();
	if (epd3 != nullptr) 
		epd3->EndCom();
	return 0;
}
int EpdBaseClr::Epd2::DecodeStatus(Epd3Base::Epd3U* epd)
{
	epd->DecodeStatus();
	//OperatingStatus
	DetectorsOn = epd->DetectorsOn;
	EPDIssued = epd->EPDIssued;
	EPDLocked = epd->EPDLocked;
	EPDTesting = epd->EPDTesting;
	EPDProcSec = epd->EPDProcSec;
	EPDFaulty = epd->EPDFaulty;

	EPDNewFault = epd->EPDNewFault;
	EPDComFault = epd->EPDComFault;
	EPDCalFault = epd->EPDCalFault;
	EPDDetFault = epd->EPDDetFault;
	EPDEprFault = epd->EPDEprFault;
	EPDTrhFault = epd->EPDTrhFault;
	EPDOthFault = epd->EPDOthFault;

	AlarmDoseHP101G = epd->AlarmDoseHP101G;
	AlarmDoseHP102G = epd->AlarmDoseHP102G;
	AlarmDoseHP07N = epd->AlarmDoseHP07N;
	AlarmRateHP101G = epd->AlarmRateHP101G;
	AlarmRateHP102G = epd->AlarmRateHP102G;
	AlarmRateHP07N = epd->AlarmRateHP07N;

	OtherAlarmRateHp101G = epd->OtherAlarmRateHp101G;
	OtherAlarmRateHp102G = epd->OtherAlarmRateHp102G;
	OtherAlarmRateHp07N = epd->OtherAlarmRateHp07N;
	OtherAlarmReturn = epd->OtherAlarmReturn;
	OtherAlarmBatLow = epd->OtherAlarmBatLow;
	OtherAlarmCarrier = epd->OtherAlarmCarrier;
	OtherAlarmBatVolt = epd->OtherAlarmBatVolt;

	return 1;
}
int EpdBaseClr::Epd2::DecodeStatus(EpdBase::Epd2U* epd)
{
	epd->DecodeStatus();
	//OperatingStatus
	DetectorsOn = epd->DetectorsOn;
	EPDIssued = epd->EPDIssued;
	EPDLocked = epd->EPDLocked;
	EPDTesting = epd->EPDTesting;
	EPDProcSec = epd->EPDProcSec;
	EPDFaulty = epd->EPDFaulty;

	EPDNewFault = epd->EPDNewFault;
	EPDComFault = epd->EPDComFault;
	EPDCalFault = epd->EPDCalFault;
	EPDDetFault = epd->EPDDetFault;
	EPDEprFault = epd->EPDEprFault;
	EPDTrhFault = epd->EPDTrhFault;
	EPDOthFault = epd->EPDOthFault;

	AlarmDoseHP101G = epd->AlarmDoseHP101G;
	AlarmDoseHP102G = epd->AlarmDoseHP102G;
	AlarmDoseHP07N = epd->AlarmDoseHP07N;
	AlarmRateHP101G = epd->AlarmRateHP101G;
	AlarmRateHP102G = epd->AlarmRateHP102G;
	AlarmRateHP07N = epd->AlarmRateHP07N;

	OtherAlarmRateHp101G = epd->OtherAlarmRateHp101G;
	OtherAlarmRateHp102G = epd->OtherAlarmRateHp102G;
	OtherAlarmRateHp07N = epd->OtherAlarmRateHp07N;
	OtherAlarmReturn = epd->OtherAlarmReturn;
	OtherAlarmBatLow = epd->OtherAlarmBatLow;
	OtherAlarmCarrier = epd->OtherAlarmCarrier;
	OtherAlarmBatVolt = epd->OtherAlarmBatVolt;

	return 1;
}
/// <summary>
/// 
/// </summary>
/// <returns>0=success</returns>
int EpdBaseClr::Epd2::GetStatus()
{
	int rv = 1;
	StatusRV = epd->ReadStatus();
	if (StatusRV != 1) GetStatusError = epd->Error; else GetStatusError= rv = 0;
	AfterGetStatus(epd);
	return rv;
}
int EpdBaseClr::Epd2::AfterGetStatus(EpdBase::Epd2U *epd)
{
	isMK3 = false;
	EPDIssued = epd->EPDIssued;
	WearerID = gcnew String((char*)epd->WearerID);
	WearerName = gcnew String((char*)epd->WearerName);
	isOn = (epd->DetectorsOn != 0);
	epdType = epd->EpdType;
	isBG = epd->isBG;
	isNG = epd->isNG;
	VersionOK = epd->VersionOK ;
	//isBG = (epd->EpdType == 0 || epd->EpdType == 4);  //MK2 BG=0 or MK3 BG=4    3=MK2 Neuruon 7=MK3 neutron
	alarmStatus = epd->AlarmStatus;
	otherAlarms = epd->OtherAlarms;
	errorStatus = epd->ErrorStatus;
	operatingStatus = epd->OperatingStatus;
	hasAlarm = epd->hasAlarm;
	EpdID = epd->EpdID;
	HardVersion = epd->HardVersion;
	SoftVersion = epd->SoftVersion;
	FunctionFlags = epd->FunctionFlags;
	CountsClock = epd->EpdClock;
	DecodeStatus(epd); 
	return 0;
}
int EpdBaseClr::Epd2::AfterGetStatus(Epd3Base::Epd3U* epd)
{
	EPDIssued= epd->EPDIssued;
	WearerID = gcnew String((char*)epd->WearerID);
	WearerName = gcnew String((char*)epd->WearerName);
	isOn = (epd->DetectorsOn != 0);
	epdType = (int)epd->EpdType;
	isBG = (epd->EpdType == EpdTypes::Mk2BetaGamma || epd->EpdType == EpdTypes::Mk3BetaGamma);  //MK2 BG=0 or MK3 BG=4    3=MK2 Neuruon 7=MK3 neutron
	isNG = epd->isNG;
	VersionOK = epd->VersionOK;
	isMK3 = epd->isMK3;
	alarmStatus = (int)epd->AlarmStatus;
	otherAlarms = (int)epd->OtherAlarms;
	errorStatus = (int)epd->ErrorStatus;
	operatingStatus = (int)epd->OperatingStatus;
	hasAlarm = epd->hasAlarm;
	EpdID = epd->EpdID;
	HardVersion = epd->HardVersion;
	SoftVersion = epd->SoftVersion;
	FunctionFlags = epd->FunctionFlags;
	CountsClock = epd->EpdClock;
	DecodeStatus( epd);
	return 0;
}
int EpdBaseClr::Epd2::AfterGetStatus()
{
	int rv = 0;
	if (isMK3)  rv=AfterGetStatus(epd3);
	else rv=AfterGetStatus(epd);
	return rv;
}

/// <summary>
/// 
/// </summary>
/// <returns>0 OK</returns>
int EpdBaseClr::Epd2::GetDoses() 
{
	int rv = 0;
	if (isMK3) 
		rv = GetDoses(epd3);
	else 
		rv = GetDoses(epd);
	return rv;
}
int EpdBaseClr::Epd2::GetDoses(EpdBase::Epd2U* epd)
{
	int rv = 1;
	Hp10 = Hp07 = 0.0;
	ReadDosesRV = epd->ReadDoses();
	if (ReadDosesRV == 1) {
		rv = AfterGetDoses(epd);
	}
	else {
		rv = 1;
		GetDosesError = epd->Error;
	}
	return rv;
}

int EpdBaseClr::Epd2::AfterGetDoses(Epd3Base::Epd3U* epd)
{
	int rv = 0;
	rv = 0;
	GetDosesError = 0;
	Hp10 = (double)epd->Hp10Dose;
	Hp07 = (double)epd->Hp07Dose;
	Hp07Peak = (double)epd->Hp07Peak;
	Hp10Peak = (double)epd->Hp10Peak;

	Hp07Total = epd->Hp07Total;
	Hp10Total = epd->Hp10Total;

	if (epd->Hp10FTime != 0) {
		//seconds since 2000 ?
		//double x = (epd->EpdClock - epd->Hp10Time) * -1.0;
		Hp10PeakTime = System::DateTime::FromFileTime(epd->Hp10FTime);
		//Hp10PeakTime =  Jan2000->AddSeconds(epd->Hp10Time);
	}
	else
		Hp10PeakTime = System::Nullable<System::DateTime>();;

	if (epd->Hp07FTime != 0) {
		//double x = (epd->EpdClock - epd->Hp07Time) * -1.0;
		Hp07PeakTime = System::DateTime::FromFileTime(epd->Hp07FTime);
		//Hp07PeakTime = Jan2000->AddSeconds(epd->Hp07Time);
	}
	else
		Hp07PeakTime = System::Nullable<System::DateTime>();

	QualityData = epd->QualityData;
	K1 = epd->K1;
	K2 = epd->K2;
	K3 = epd->K3;
	K4 = epd->K4;
	K5 = epd->K5;
	K6 = epd->K6;
	SG = epd->SG;
	BC = epd->SG;
	FB = epd->FB;
	HG = epd->HG;
	NGgain = K3;
	return rv;
}
/// <summary>
/// 
/// </summary>
/// <param name="epd"></param>
/// <returns>0 OK</returns>
int EpdBaseClr::Epd2::GetDoses(Epd3Base::Epd3U* epd)
{
	int rv = 1;
	Hp10 = Hp07 = 0.0;
	int ReadDosesRV = epd->ReadDoses();

	if (ReadDosesRV == 0) {
		rv = AfterGetDoses(epd3);
	} 
	else {
		rv = 1;
		GetDosesError = epd->Error;
	}
	return rv;
}

/// <summary>
/// 
/// </summary>
/// <returns>0 OK</returns>
int EpdBaseClr::Epd2::SetDeIssued()
{
	int rv = 0;
	if (isMK3) rv = epd3->DeIssue();
	else rv = epd->DeIssue();
	return rv;
}
int EpdBaseClr::Epd2::PrepareForIssue()
{
	int rv = 0;
	PrepareForIssueError = 0;
	if (isMK3) rv= epd3->PrepareForIssue();
	else rv= epd->PrepareForIssue();
	if (rv != 0) PrepareForIssueError = epd->Error;
	return rv;
}
/// <summary>
/// 
/// </summary>
/// <returns>0 OK</returns>
int EpdBaseClr::Epd2::SetIssued()
{
	int rv = 0;
	if (isMK3) rv=SetIssued(epd3);
	else rv=SetIssued(epd);
	return rv;
}


int EpdBaseClr::Epd2::BeforeSetIssued(Epd3Base::Epd3U* epd)
{
	int rv = 0;
	SetIssuedError = 0;
	epd->Hp07THDose = Hp07THDose;
	epd->Hp10THDose1 = Hp10THDose1;
	epd->Hp10THDose2 = Hp10THDose2;

	epd->Hp10Rate1On = Hp10Rate1On;
	epd->Hp10Rate2On = Hp10Rate2On;
	epd->Hp07RateOn = Hp07RateOn;
	epd->Hp10Rate1Off = Hp10Rate1Off;
	epd->Hp10Rate2Off = Hp10Rate2Off;
	epd->Hp07RateOff = Hp07RateOff;

	memset(epd->WearerID, ' ', WearerIDLength); epd->WearerID[WearerIDLength] = 0;
	char* str1 = (char*)(void*)Runtime::InteropServices::Marshal::StringToHGlobalAnsi(WearerID);
	int l = strlen(str1);
	if (l > WearerIDLength) l = WearerIDLength;
	_memccpy(epd->WearerID + WearerIDLength - l, str1, l, WearerIDLength);
	Runtime::InteropServices::Marshal::FreeHGlobal((IntPtr)str1);

	memset(epd->WearerName, 0, WearerNameLength + 1);
	char* str2 = (char*)(void*)Runtime::InteropServices::Marshal::StringToHGlobalAnsi(WearerName);
	l = strlen(str2);
	if (l > WearerNameLength) l = WearerNameLength;
	_memccpy(epd->WearerName, str2, l, WearerNameLength);
	Runtime::InteropServices::Marshal::FreeHGlobal((IntPtr)str2);

	return 0;
}
/// <summary>
/// 
/// </summary>
/// <param name="epd"></param>
/// <returns>0 success</returns>
int EpdBaseClr::Epd2::SetIssued(Epd3Base::Epd3U* epd)
{
	int rv = 0;
	rv =  BeforeSetIssued(epd);
	rv = epd->Issue();
	if (rv != 0) SetIssuedError = epd->Error;
	return rv;
}

int EpdBaseClr::Epd2::BeforeSetIssued(EpdBase::Epd2U* epd)
{
	int rv = 0;
	SetIssuedError = 0;
	epd->Hp07THDose = (DWORD)(Hp07THDose * 64.0);
	epd->Hp10THDose1 = (DWORD)(Hp10THDose1 * 64.0);
	epd->Hp10THDose2 = (DWORD)(Hp10THDose2 * 64.0);

	epd->Hp10Rate1On = (DWORD)(Hp10Rate1On);
	epd->Hp10Rate2On = (DWORD)(Hp10Rate2On);
	epd->Hp07RateOn = (DWORD)(Hp07RateOn);
	epd->Hp10Rate1Off = (DWORD)(Hp10Rate1Off);
	epd->Hp10Rate2Off = (DWORD)(Hp10Rate2Off);
	epd->Hp07RateOff = (DWORD)(Hp07RateOff);

	memset(epd->WearerID, ' ', WearerIDLength); epd->WearerID[WearerIDLength] = 0;
	char* str1 = (char*)(void*)Runtime::InteropServices::Marshal::StringToHGlobalAnsi(WearerID);
	int l = strlen(str1);
	if (l > WearerIDLength) l = WearerIDLength;
	_memccpy(epd->WearerID + WearerIDLength - l, str1, l, WearerIDLength);
	Runtime::InteropServices::Marshal::FreeHGlobal((IntPtr)str1);

	memset(epd->WearerName, 0, WearerNameLength + 1);
	char* str2 = (char*)(void*)Runtime::InteropServices::Marshal::StringToHGlobalAnsi(WearerName);
	l = strlen(str2);
	if (l > WearerNameLength) l = WearerNameLength;
	_memccpy(epd->WearerName, str2, l, WearerNameLength);
	Runtime::InteropServices::Marshal::FreeHGlobal((IntPtr)str2);

	
	return 0;
}
int EpdBaseClr::Epd2::SetIssued(EpdBase::Epd2U* epd)
{
	int rv = 0;
	BeforeSetIssued(epd);
	rv = epd->Issue();
	if (rv != 0) SetIssuedError = epd->Error;
	return rv;
}
int EpdBaseClr::Epd2::WriteCalibration()
{
	int rv = 0;
	if (isMK3) rv = WriteCalibration(epd3);
	else rv = WriteCalibration(epd);
	return rv;
}
int EpdBaseClr::Epd2::WriteCalibration(EpdBase::Epd2U* epd)
{
	epd->K1 = K1;
	epd->K2 = K2;

	epd->K3 = K3;
	epd->K4 = K4;

	epd->K5 = K5;
	epd->K6 = K6;

	//epd->K1 = 903;
	//epd->K2 = 613;
	//epd->K5 = 13100;
	//epd->K6 = 1310;

	int rv = epd->WriteCal();
	return rv;

}

int EpdBaseClr::Epd2::WriteCalibration(Epd3Base::Epd3U* epd)
{
	epd->K1 = K1;
	epd->K2 = K2;

	epd->K3 = K3;
	epd->K4 = K4;

	epd->K5 = K5;
	epd->K6 = K6;

	//epd->K1 = 903;
	//epd->K2 = 613;
	//epd->K5 = 13100;
	//epd->K6 = 1310;

	int rv = epd->WriteCal();
	return rv;

}
/// <summary>
/// 
/// </summary>
/// <returns>0=success</returns>
int EpdBaseClr::Epd2::ReadTresholds()
{
	int rv = 0;
	if (isMK3)
		rv = ReadTresholds(epd3);
	else
		rv = ReadTresholds(epd);
	return rv;
}


int EpdBaseClr::Epd2::AfterReadTresholds(EpdBase::Epd2U* epd)
{
	int rv = 0;
	Hp10THDose1 = (double)epd->Hp10THDose1 / 64.0;
	Hp10THDose2 = (double)epd->Hp10THDose2 / 64.0;
	Hp07THDose = (double)epd->Hp07THDose / 64.0;

	Hp10Rate1On = (double)epd->Hp10Rate1On;
	Hp10Rate2On = (double)epd->Hp10Rate2On;
	Hp07RateOn = (double)epd->Hp07RateOn;
	Hp10Rate1Off = (double)epd->Hp10Rate1Off;
	Hp10Rate2Off = (double)epd->Hp10Rate2Off;
	Hp07RateOff = (double)epd->Hp07RateOff;

	K1 = epd->K1;
	K2 = epd->K2;
	K3 = epd->K3;
	K4 = epd->K4;
	K5 = epd->K5;
	K6 = epd->K6;
	SG = epd->SG;
	BC = epd->BC;
	FB = epd->FB;
	HG = epd->HG;

	NGgain = K3;

	return rv;

}
/// <summary>
/// 
/// </summary>
/// <param name="epd"></param>
/// <returns>0 = Success</returns>
int EpdBaseClr::Epd2::ReadTresholds(EpdBase::Epd2U* epd)
{
	ReadTresholdsError = 0;
	int rv = epd->ReadTresHolds();
	if (rv != 0) ReadTresholdsError = epd->Error;
	rv = AfterReadTresholds(epd);
	return rv;
}

int EpdBaseClr::Epd2::AfterReadTresholds(Epd3Base::Epd3U* epd)
{
	int rv = 0;
	Hp10THDose1 = (double)epd->Hp10THDose1;
	Hp10THDose2 = (double)epd->Hp10THDose2;
	Hp07THDose = (double)epd->Hp07THDose;

	
	Hp10Rate1On = (double)epd->Hp10Rate1On;
	Hp10Rate2On = (double)epd->Hp10Rate2On;
	Hp07RateOn = (double)epd->Hp07RateOn;
	Hp10Rate1Off = (double)epd->Hp10Rate1Off;
	Hp10Rate2Off = (double)epd->Hp10Rate2Off;
	Hp07RateOff = (double)epd->Hp07RateOff;


	Hp10Total = (double)epd->Hp10Total;
	Hp07Total = (double)epd->Hp07Total;


	K1 = epd->K1;
	K2 = epd->K2;
	K3 = epd->K3;
	K4 = epd->K4;
	K5 = epd->K5;
	K6 = epd->K6;
	SG = epd->SG;
	BC = epd->BC;
	FB = epd->FB;
	HG = epd->HG;

	NGgain = K3;
	return rv;
}
/// <summary>
/// 
/// </summary>
/// <param name="epd"></param>
/// <returns>0 Success</returns>
int EpdBaseClr::Epd2::ReadTresholds(Epd3Base::Epd3U* epd)
{
	int rv = 0;
	ReadTresholdsError = 0;
	rv= epd->ReadAlarmTresholds();
	rv = epd->ReadSensitivitiesAndTresholds();
	if (rv != 0) ReadTresholdsError = epd->Error;
	rv = AfterReadTresholds(epd);
	return rv;
}
/// <summary>
/// 
/// </summary>
/// <returns>0=Success</returns>
int EpdBaseClr::Epd2::ReadExtraStatus()
{
	int rv = 0;
	if (isMK3) rv = ReadExtraStatus(epd3);
	else rv = ReadExtraStatus(epd);
	return rv;
}
int EpdBaseClr::Epd2::ReadExtraStatus(EpdBase::Epd2U* epd)
{
	int rv = epd->EPDReadExtraStatus();
	BatADC = epd->byBatADC;
	SupplyADC = epd->bySupplyADC;

	D1 = epd->D1 - epd->BaseD1;
	D2 = epd->D2 - epd->BaseD2;
	D3 = epd->D3 - epd->BaseD3;
	D4 = epd->D4 - epd->BaseD4;
	CountsClock = epd->CountsClock;
	CountsClockBase = epd->BaseCountsClock;

	return rv;
}
int EpdBaseClr::Epd2::ReadExtraStatus(Epd3Base::Epd3U* epd)
{
	int rv = epd->EPDReadExtraStatus();
	BatADC = 0;  //epd->byBatADC;
	SupplyADC = 0; // epd->bySupplyADC;

	D1 = epd->D1 - epd->BaseD1;
	D2 = epd->D2 - epd->BaseD2;
	D3 = epd->D3 - epd->BaseD3;
	D4 = epd->D4 - epd->BaseD4;
	CountsClock = epd->CountsClock;
	CountsClockBase = epd->BaseCountsClock;

	return rv;
}
int  EpdBaseClr::Epd2::AfterGetDoses(EpdBase::Epd2U* epd)
{
		int rv = 0;
		GetDosesError = 0;
		Hp10 = (double)epd->Hp10Dose / 64.0;
		Hp07 = (double)epd->Hp07Dose / 64.0;
		Hp07Peak = (double)epd->Hp07Peak / 64.0;
		Hp10Peak = (double)epd->Hp10Peak / 64.0;

		Hp07Total = epd->Hp07Total / 64.0;
		Hp10Total = epd->Hp10Total / 64.0;
	
	if (epd->Hp10FTime != 0) {
		try {
			Hp10PeakTime = System::DateTime::FromFileTime(epd->Hp10FTime);
		}
		catch (System::Exception^ ex) {
			Hp10PeakTime = System::Nullable<System::DateTime>(); 
		}
		//double x = (epd->EpdClock - epd->Hp10Time) * -1.0;
		//Hp10PeakTime = System::DateTime::Now.AddSeconds(x);
	}
	else
		Hp10PeakTime = System::Nullable<System::DateTime>();
	if (epd->Hp07FTime != 0) {
		try {
		Hp07PeakTime = System::DateTime::FromFileTime(epd->Hp07FTime);
		}
		catch (System::Exception^ ex) {
			Hp10PeakTime = System::Nullable<System::DateTime>();
		}
		//double x = (epd->EpdClock - epd->Hp07Time) * -1.0;
		//Hp07PeakTime = System::DateTime::Now.AddSeconds(x);
	}
	else
		Hp10PeakTime = System::Nullable<System::DateTime>();

	QualityData = epd->QualityData;
	K1 = epd->K1;
	K2 = epd->K2;
	K3 = epd->K3;
	K4 = epd->K4;
	K5 = epd->K5;
	K6 = epd->K6;
	SG = epd->SG;
	BC = epd->SG;
	FB = epd->FB;
	HG = epd->HG;

	NGgain = K3;
	return rv;
}
/// <summary>
/// Get Doses and tresholds, and close if requested
/// </summary>
/// <param name="close"></param>
/// <returns></returns>
int EpdBaseClr::Epd2::GetAll(bool close)
{
	int rv = 0;
	if (!isMK3) {
		rv = epd->GetAll(close);
		rv = AfterGetDoses(epd);
		rv = AfterReadTresholds(epd);
	}
	else
	{
		rv = epd3->GetAll(close);
		rv = AfterGetDoses(epd3);
		rv = AfterReadTresholds(epd3);
	}
	return rv;
}
int EpdBaseClr::Epd2::GetAllDeissue()
{
	int rv = 0;
	if (!isMK3) {
		rv = epd->GetAllDeissue();
		rv = AfterGetDoses(epd);
		rv = AfterReadTresholds(epd);
	}
	else
	{
		rv = epd3->GetAllDeissue();
		rv = AfterGetDoses(epd3);
		rv = AfterReadTresholds(epd3);
	}
	return rv;
}
/// <summary>
/// Clear Doses, for Neutron : get and check K, Issue
/// </summary>
/// <param name="gain"></param>
/// <returns></returns>
int EpdBaseClr::Epd2::IssueAndCheck(float gain)
{
	int rv = 0;
	if (!isMK3) {
		BeforeSetIssued(epd);
		rv = epd->IssueAndCheck(gain);
	}
	else
	{
		BeforeSetIssued(epd3);
		rv = epd3->IssueAndCheck(gain);
	}
	return rv;
}
int EpdBaseClr::Epd2::SwitchCon()
{
	int rv = 0;
	if (isMK3) {
		if (epd3->epdComsHandle == INVALID_HANDLE_VALUE) {
			epd->EndCom();  rv=epd3->StartCom();
		}
	}
	else {
		if (epd->CommsInitialized == 0) {
			epd3->EndCom();  
			rv = epd->StartCom(); //0=ok
			if (!rv) rv = epd->Open(EpdID);
			if (!rv) rv = epd->ReadStatus();
			
		}
	}
	return rv;
}
void EpdBaseClr::Epd2::InitData()
{
	ConnectError = 0;
	EpdID = 0;
	DeviceCount = 0;
	GetStatusError = 0;  StatusRV = 0; EPDIssued = false;
	WearerID = String::Empty;
	WearerName = String::Empty;
	isOn = 0;
	epdType = 0;
	isBG = 0;
	alarmStatus = 0;
	otherAlarms = 0;
	errorStatus = 0;
	operatingStatus = 0;
	HardVersion = 0;
	SoftVersion = 0;
	FunctionFlags = 0;
	CountsClock = 0;
}
/// <summary>
/// connect to Epd and read status
/// </summary>
/// <returns>0=success 1=Connect error 2=TO 3=StatusReadError</returns>
int EpdBaseClr::Epd2::ConnectAndStatus()
{
	int rv = 1;
	InitData();
	epd->EndCom();
	rv = epd3->ConnectAndStatus(tokenSourceTimeout);
	if (rv==0) {
		DeviceCount = epd3->DeviceCount;
		EpdID = epd3->EpdID; 
		epd->EpdID = epd3->EpdID;
		isMK3 = epd3->isMK3;
		isBG = epd3->isBG;
		isNG = epd3->isNG;
		if (isMK3) {
			AfterGetStatus(epd3);
		}
		else {
			rv = SwitchCon();
			AfterGetStatus(epd);
		}
		if (isTitleNG != isNG) {
			if (isNG) {
				Hp10Name = gcnew String(tHp10G); Hp07Name = gcnew String(tHp07N);  
			}
			else { 
				Hp10Name = gcnew String(tHp10); Hp07Name = gcnew String(tHp07);  
			}
			isTitleNG = isNG;
		}
	}
	else 
		ConnectError = epd->Error;
	return rv;
}
void EpdBaseClr::Epd2::WaitEpd()
{
	int rv = 0; //start
	System::Threading::CancellationToken^ token = tokenSource->Token;
	rv = ConnectAndStatus();
	/*if (token->IsCancellationRequested && rv != 2) {
		rv = 2;
	}*/
	if (rv == 0) {
		if (_EpdRead != nullptr)
			_EpdRead(this, gcnew EpdEventArgs(EpdID, EPDIssued, isBG, isMK3));
	}
	else if (rv == 2 && _EpdTO != nullptr) {
		_EpdTO(this, gcnew  EpdTOEventArgs(epd3->ConnectTries, epd3->ConnectTimerFired));
	}
	else if (rv > 0 && _EpdError != nullptr) {
		_EpdError(this, gcnew EpdErrorEventArgs(rv));
	}
	return;
}
System::Threading::Tasks::Task^ EpdBaseClr::Epd2::Wait(int timeout, int Retries)
{
	if (waitTask == nullptr)
	{
		tokenSourceTimeout = timeout;
		tokenSource = gcnew System::Threading::CancellationTokenSource(tokenSourceTimeout + 500);
		readRetries = Retries;
		waitTask = System::Threading::Tasks::Task::Run(gcnew Action(this, &Epd2::WaitEpd)); // System::Threading::Tasks::Task::Factory->cre(gcnew Action(this, &CCard::WaitBadge), tokenSource->Token);
	}
	else {
		tokenSource = gcnew System::Threading::CancellationTokenSource(tokenSourceTimeout - 100);
	}
	return waitTask;
}
void EpdBaseClr::Epd2::WaitEnd()
{
	if (waitTask != nullptr)
	{
		//if (epd3->hWaitTimer!= nullptr) 
		//	SetEvent(epd3->hWaitTimer);
		waitTask->Wait(750);
		if (waitTask->Status == System::Threading::Tasks::TaskStatus::Running) {
			tokenSource->Cancel();
			waitTask->Wait(1000);
		}
		delete waitTask; 
		waitTask = nullptr;
		delete tokenSource; 
		tokenSource = nullptr;
		Close();
	}
}