#include "stdafx.h"
#include "TimeFunctions.h"

#pragma unmanaged

TimeFunctions::TimeFunctions()
{
	lu.LL = 0;
}


UINT32  FileTime_to_POSIX(FILETIME ft)
{
	// takes the last modified date
	LARGE_INTEGER date, adjust;
	date.HighPart = ft.dwHighDateTime;
	date.LowPart = ft.dwLowDateTime;

	// 100-nanoseconds = milliseconds * 10000
	adjust.QuadPart = 11644473600000 * 10000;

	// removes the diff between 1970 and 1601
	date.QuadPart -= adjust.QuadPart;

	// converts back from 100-nanoseconds to seconds
	return (UINT32)(date.QuadPart / 10000000);
}

UINT32 UnixTimeNow() {
	FILETIME ft;
	GetSystemTimeAsFileTime(&ft);
	return FileTime_to_POSIX(ft);
}

void TimeFunctions::UnixTimeToFileTime(time_t t, LPFILETIME pft)
{
	// Note that LONGLONG is a 64-bit value
	LONGLONG ll;
	
	ll = Int32x32To64(t, 10000000) + 116444736000000000;
	pft->dwLowDateTime = (DWORD)ll;
	pft->dwHighDateTime = ll >> 32;
}

 void TimeFunctions::UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst)
{
	FILETIME ft;
	UnixTimeToFileTime(t, &ft);
	FileTimeToSystemTime(&ft, pst);
}


 void TimeFunctions::EpdTimeToFileTime(INT32 t, LPFILETIME pft, bool isMK2)  //MK3
 {
	 LONGLONG offset;
	 if (isMK2) offset = 116444736000000000; else offset = 125911584000000000;;
	 LONGLONG ll;
	 ll = Int32x32To64(t, 10000000) + offset;  //1601-1-1 -> 2000
	 pft->dwLowDateTime = (DWORD)ll;
	 pft->dwHighDateTime = ll >> 32;
 }

 void TimeFunctions::FileTimeToEpdTime(FILETIME pft, INT32* t, bool isMK2)
 {
	 LONGLONG offset;
	 if (isMK2) offset = 116444736000000000; else offset = 125911584000000000;
	 LONGLONG ll = ((((LONGLONG)pft.dwHighDateTime << 32) + pft.dwLowDateTime) - offset) / 10000000;
	 *t = (DWORD)ll;
 }

 UINT32 TimeFunctions::NowToEpdTime(bool isMK2)
 {
	 LONGLONG offset;
	 if (isMK2) offset = 116444736000000000; else offset = 125911584000000000;
	 SYSTEMTIME t;
	 GetSystemTime(&t);
	 FILETIME ft;
	 SystemTimeToFileTime((const SYSTEMTIME*)&t, &ft);
	 LONGLONG ll = ((((LONGLONG)ft.dwHighDateTime << 32U) + ft.dwLowDateTime) - offset) / 10000000;
	 return (DWORD)ll;
 }

 void TimeFunctions::EPD2PeakTimeToFiletime(DWORD EpdClock, DWORD EpdPeakTime, FILETIME *PeakFileTime ) {
	 if (EpdPeakTime != 0xCDCDCDCD) {
		 UINT32 tm = EpdClock - EpdPeakTime;
		 GetSystemTimeAsFileTime(&lu.FT);
		 lu.LL -= UInt32x32To64(tm, 10000000);
		 *PeakFileTime = lu.FT;
	 }
	 else {
		 (*PeakFileTime).dwLowDateTime = (*PeakFileTime).dwHighDateTime = 0;
	 }
 }
 