//////////////////////////////////////////////////////////////////////////////
//
// Asura_Platform_Time_System.cpp
//
// Copyright (c) 2007 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

/******************************************************************************/
/* Included Files                                                             */
/******************************************************************************/

#include "Core/Asura.h"

#include "Core/Asura_Time_System.h"

// Asura Platform-independent
#include "Debugging/Asura_Assert.h"

// Misc
#include <time.h>
#include <xtl.h>

/******************************************************************************/
/* Asura_Time_System Static Class Functions                                   */
/******************************************************************************/

////////////////////////////////////////////////////////////////////////////////
//
// Asura_Time_System::Platform_GetCurrentDateAndTime()
//
// Fills Asura_Time_System::s_xTime with the current system date and time
//
// Parameters:		None
// Return value:	None
//
////////////////////////////////////////////////////////////////////////////////

void Asura_Time_System::Platform_GetCurrentDateAndTime()
{
	SYSTEMTIME xST;

	GetLocalTime( &xST );

	s_xTime.m_ucSecond     = static_cast< u_char  >( xST.wSecond );
	s_xTime.m_ucMinute     = static_cast< u_char  >( xST.wMinute );
	s_xTime.m_ucHour       = static_cast< u_char  >( xST.wHour );
	s_xTime.m_ucDayOfWeek  = static_cast< u_char  >( xST.wDayOfWeek );
	s_xTime.m_ucDayOfMonth = static_cast< u_char  >( xST.wDay - 1 );                // Asura dates are zero-based
	s_xTime.m_ucMonth      = static_cast< u_char  >( xST.wMonth - 1 );              // January = 1 in SYSTEMTIME
	s_xTime.m_usYear       = static_cast< u_short >( xST.wYear );
}

////////////////////////////////////////////////////////////////////////////////
//
// Asura_Time_System::Platform_GetTimeZoneBias()
//
// Queries the system time zone bias in minutes. UTC = local time + bias
//
// Parameters:		None
// Return value:	Time zone bias
//
////////////////////////////////////////////////////////////////////////////////

int Asura_Time_System::Platform_GetTimeZoneBias()
{
	TIME_ZONE_INFORMATION xTZ;

	#if defined ASURA_ASSERT
		const DWORD uResult =
	#endif
		GetTimeZoneInformation( &xTZ );

	Asura_Assert( uResult != TIME_ZONE_ID_UNKNOWN, "Failed to get time zone information." );

	return xTZ.Bias;
}

/******************************************************************************/
/* Asura_Time Class Functions                                                 */
/******************************************************************************/

////////////////////////////////////////////////////////////////////////////////
//
// Asura_Time::Platform_FillFromLibCTime
//
// Fills the members of Asura_Time from a given LibC value (time_t)
//
// Parameters:		uLibCTime - Seconds since 00:00:00 1 January 1970 (UTC)
// Return value:	None
//
////////////////////////////////////////////////////////////////////////////////

void Asura_Time::Platform_FillFromLibCTime( u_int uLibCTime )
{
	const time_t xTimeT = uLibCTime;

	const tm* const pxLibCTimeBlock = gmtime( &xTimeT );
	Asura_Assert( pxLibCTimeBlock, "Failed to convert time_t to tm." );

	if( pxLibCTimeBlock )
	{
		m_usYear       = static_cast< u_short >( pxLibCTimeBlock->tm_year + 1900 );
		m_ucMonth      = static_cast< u_char  >( pxLibCTimeBlock->tm_mon );            // January = 0 in tm
		m_ucDayOfMonth = static_cast< u_char  >( pxLibCTimeBlock->tm_mday - 1 );       // Sunday = 0 in tm
		m_ucHour       = static_cast< u_char  >( pxLibCTimeBlock->tm_hour );
		m_ucMinute     = static_cast< u_char  >( pxLibCTimeBlock->tm_min );
		m_ucSecond     = static_cast< u_char  >( pxLibCTimeBlock->tm_sec );
	}
}
