//! \~\file pitime_win.h
//! \~\ingroup Types
//! \brief
//! \~english PITime conversions for Windows
//! \~russian Преобразования PITime для Windows
//! \details
//! \~english This file provides conversion functions between Windows time structures (FILETIME, SYSTEMTIME) and PIP time structures
//! (PISystemTime, PIDateTime).
//! \~russian Этот файл предоставляет функции преобразования между структурами времени Windows (FILETIME, SYSTEMTIME) и структурами времени
//! PIP (PISystemTime, PIDateTime).
/*
    PIP - Platform Independent Primitives
    PITime conversions for Windows
    Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PITIME_WIN_H
#define PITIME_WIN_H

#include "pibase.h"
#ifdef WINDOWS

#  include "pitime.h"

#  include <windows.h>

//! \~\ingroup Types
//! \~english Converts FILETIME to PISystemTime.
//! \~russian Преобразует FILETIME в PISystemTime.
//! \details
//! \~english Converts Windows FILETIME structure to PISystemTime. FILETIME is a 64-bit value representing the number of 100-nanosecond
//! intervals since January 1, 1601 (UTC).
//! \~russian Преобразует структуру Windows FILETIME в PISystemTime. FILETIME - это 64-битное значение, представляющее количество интервалов
//! по 100 наносекунд с 1 января 1601 года (UTC).
inline PISystemTime FILETIME2PISystemTime(const FILETIME & t) {
	PISystemTime st;
	ullong lt      = ullong(t.dwHighDateTime) * 0x100000000U + ullong(t.dwLowDateTime);
	st.seconds     = lt / 10000000U;
	st.nanoseconds = (lt % 10000000U) * 100U;
	return st;
}


//! \~\ingroup Types
//! \~english Converts SYSTEMTIME to PIDateTime.
//! \~russian Преобразует SYSTEMTIME в PIDateTime.
//! \details
//! \~english Converts Windows SYSTEMTIME structure to PIDateTime. SYSTEMTIME represents a date and time using individual members for month,
//! day, year, etc.
//! \~russian Преобразует структуру Windows SYSTEMTIME в PIDateTime. SYSTEMTIME представляет дату и время с помощью отдельных членов для
//! месяца, дня, года и т.д.
inline PIDateTime SYSTEMTIME2PIDateTime(const SYSTEMTIME & t) {
	PIDateTime dt;
	dt.year         = t.wYear;
	dt.month        = t.wMonth;
	dt.day          = t.wDay;
	dt.hours        = t.wHour;
	dt.minutes      = t.wMinute;
	dt.seconds      = t.wSecond;
	dt.milliseconds = t.wMilliseconds;
	return dt;
}

//! \~\ingroup Types
//! \~english Converts FILETIME to PIDateTime.
//! \~russian Преобразует FILETIME в PIDateTime.
//! \details
//! \~english Converts Windows FILETIME to PIDateTime. The FILETIME is first converted to local time, then to SYSTEMTIME, and finally to
//! PIDateTime.
//! \~russian Преобразует Windows FILETIME в PIDateTime. Сначала FILETIME преобразуется в местное время, затем в SYSTEMTIME и наконец в
//! PIDateTime.
inline PIDateTime FILETIME2PIDateTime(const FILETIME & t) {
	FILETIME lt;
	SYSTEMTIME st;
	FileTimeToLocalFileTime(&t, &lt);
	FileTimeToSystemTime(&lt, &st);
	return SYSTEMTIME2PIDateTime(st);
}

//! \~\ingroup Types
//! \~english Converts PIDateTime to SYSTEMTIME.
//! \~russian Преобразует PIDateTime в SYSTEMTIME.
//! \details
//! \~english Converts PIDateTime to Windows SYSTEMTIME structure.
//! \~russian Преобразует PIDateTime в структуру Windows SYSTEMTIME.
inline SYSTEMTIME PIDateTime2SYSTEMTIME(const PIDateTime & dt) {
	SYSTEMTIME st;
	st.wYear         = dt.year;
	st.wMonth        = dt.month;
	st.wDay          = dt.day;
	st.wHour         = dt.hours;
	st.wMinute       = dt.minutes;
	st.wSecond       = dt.seconds;
	st.wMilliseconds = dt.milliseconds;
	return st;
}

//! \~\ingroup Types
//! \~english Converts PIDateTime to FILETIME.
//! \~russian Преобразует PIDateTime в FILETIME.
//! \details
//! \~english Converts PIDateTime to Windows FILETIME. The PIDateTime is first converted to SYSTEMTIME, then to local FILETIME, and finally
//! to UTC FILETIME.
//! \~russian Преобразует PIDateTime в Windows FILETIME. Сначала PIDateTime преобразуется в SYSTEMTIME, затем в местное FILETIME и наконец в
//! UTC FILETIME.
inline FILETIME PIDateTime2FILETIME(const PIDateTime & dt) {
	FILETIME lt, ret;
	SYSTEMTIME st = PIDateTime2SYSTEMTIME(dt);
	SystemTimeToFileTime(&st, &lt);
	LocalFileTimeToFileTime(&lt, &ret);
	return ret;
}


#endif // WINDOWS
#endif // PITIME_WIN_H
