//////////////////////////////////////////////////////////////////////////////
//
// Asura_PC_SteamworksStats.cpp
//
// Copyright (c) 2009 Rebellion. All rights reserved.
//
// Description:
//
//     Asura wrapper class for steam user stats storage
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

#include "Core/Asura.h"

#ifdef ASURA_PC_SUPPORT_STEAMWORKS

// This file's header.
#include "Network/Steamworks/Asura_PC_SteamworksStats.h"

#include "Debugging/Asura_Logfile.h"

Asura_PC_Steam_Callback< UserStatsReceived_t > Asura_PC_SteamworksStats::s_xCallback_StatsReceived(Asura_PC_SteamworksStats::Callback_StatsReceived);
Asura_PC_Steam_Callback< UserStatsStored_t > Asura_PC_SteamworksStats::s_xCallback_StatsStored(Asura_PC_SteamworksStats::Callback_StatsStored);

bool Asura_PC_SteamworksStats::s_bStatsRequested(false);
bool Asura_PC_SteamworksStats::s_bStatsReceived(false);
bool Asura_PC_SteamworksStats::s_bStoreStats(false);

void Asura_PC_SteamworksStats::Initialise()
{
	s_xCallback_StatsReceived.Register();
	s_xCallback_StatsStored.Register();
}

void Asura_PC_SteamworksStats::Update()
{
	if( Asura_PC_Steamworks::IsInitialised() )
	{
		// NY - 24 March 2009 - request stats from steam once all logged in and working. silently fail
		if (!s_bStatsRequested)
		{
			if (SteamUser() && SteamUser()->BLoggedOn() && SteamUserStats())
			{
				if ( SteamUserStats()->RequestCurrentStats( ))
				{
					s_bStatsRequested = true;
				}
			}
			return;
		}
		if (s_bStatsReceived && s_bStoreStats)
		{
			SteamUserStats()->StoreStats();
			s_bStoreStats = false;
		}
	}
}

void Asura_PC_SteamworksStats::Shutdown()
{
	s_xCallback_StatsReceived.Unregister();
	s_xCallback_StatsStored.Unregister();
}

bool Asura_PC_SteamworksStats::IsInitComplete()
{
	return s_bStatsReceived;
}

void Asura_PC_SteamworksStats::StoreStats()
{
	s_bStoreStats = true;
}


void Asura_PC_SteamworksStats::SetStat(const char* szStat, int iValue)
{
	if (s_bStatsReceived)
	{
		SteamUserStats()->SetStat(szStat, iValue);
	}
}

void Asura_PC_SteamworksStats::IncrementStat(const char* szStat, int iIncrement)
{
	if (s_bStatsReceived)
	{
		int iTotal;
		SteamUserStats()->GetStat(szStat, &iTotal);
		iTotal += iIncrement;
		SteamUserStats()->SetStat(szStat, iTotal);
	}
}

void Asura_PC_SteamworksStats::SetStat(const char* szStat, float fValue)
{
	if (s_bStatsReceived)
	{
		SteamUserStats()->SetStat(szStat, fValue);
	}
}

void Asura_PC_SteamworksStats::IncrementStat(const char* szStat, float fIncrement)
{
	if (s_bStatsReceived)
	{
		float fTotal;
		SteamUserStats()->GetStat(szStat, &fTotal);
		fTotal += fIncrement;
		SteamUserStats()->SetStat(szStat, fTotal);
	}
}

void Asura_PC_SteamworksStats::UpdateAverageStat(const char* szStat, float fIncrement, float fTimeIncrement)
{
	if (s_bStatsReceived)
	{
		SteamUserStats()->UpdateAvgRateStat(szStat, fIncrement, Asura_Maths::FtoD(fTimeIncrement));
	}
}

int Asura_PC_SteamworksStats::GetIntStat(const char* szStat)
{
	int iValue = 0;
	if (s_bStatsReceived)
	{
		SteamUserStats()->GetStat(szStat, &iValue);
	}
	return iValue;
}

float Asura_PC_SteamworksStats::GetFloatStat(const char* szStat)
{
	float fValue = 0;
	if (s_bStatsReceived)
	{
		SteamUserStats()->GetStat(szStat, &fValue);
	}
	return fValue;
}

void Asura_PC_SteamworksStats::Callback_StatsReceived ( const UserStatsReceived_t* const pxParam )
{
	// we may get callbacks for other games' stats arriving, ignore them
	CGameID xGameID( SteamUtils()->GetAppID() );
	if ( xGameID.ToUint64() == pxParam->m_nGameID )
	{
		if ( k_EResultOK == pxParam->m_eResult )
		{
			s_bStatsReceived = true;
			Asura_OutputToDebugger(( "Steamworks callback : Stats received ok\n" ));
		}
	}
}

void Asura_PC_SteamworksStats::Callback_StatsStored ( const UserStatsStored_t* const pxParam )
{
	// we may get callbacks for other games' stats arriving, ignore them
	CGameID xGameID( SteamUtils()->GetAppID() );
	if ( xGameID.ToUint64() == pxParam->m_nGameID )
	{
		if (pxParam->m_eResult == k_EResultOK)
		{
			Asura_OutputToDebugger(( "Steamworks callback : Stats stored ok\n" ));
		}
		else if (pxParam->m_eResult ==  k_EResultInvalidParam)
		{
			// One or more stats we set broke a constraint. They've been reverted,
			// and we should re-iterate the values now to keep in sync.
			Asura_OutputToDebugger(( "Steamworks callback : Stats bad param\n" ));
			// Fake up a callback here so that we re-load the values.
			UserStatsReceived_t callback;
			callback.m_eResult = k_EResultOK;
			callback.m_nGameID = xGameID.ToUint64();
			Callback_StatsReceived( &callback );
		}
		else
		{
			Asura_OutputToDebugger(( "Steamworks callback : Stats store failed\n" ));
		}
	}
}
#endif // #ifdef ASURA_PC_SUPPORT_STEAMWORKS
