//////////////////////////////////////////////////////////////////////////////
//
// Asura_Project_PC_SteamworksLeaderboards.cpp
//
// Copyright (c) 2009 Rebellion. All rights reserved.
//
// Description:
//
//     AVP leaderboard PC implementation
//
//////////////////////////////////////////////////////////////////////////////

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

#include "Core/Asura.h"

#ifdef ASURA_SUPPORT_LEADERBOARDS
#ifdef ASURA_PC_SUPPORT_STEAMWORKS

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

#include "Network/Online/Asura_Leaderboards.h"
#include "Network/Steamworks/Asura_PC_SteamworksStats.h"

#include "Core/AVP_Settings.h"
#include "Entity/PlayerInfo/AVP_ClientEntity_PlayerInfo.h"
#include "Network/AVP_Leaderboards.h"

static const char* aszAVP_PC_LEADERBOARD_BOARDNAME[AVP_NUM_LEADERBOARDS] = 
{
	// NY - 27 April 2009 - obfuscated names until avp has own steam ID
	"RB_TEST_1",								// AVP_LEADERBOARD_KILLS,
	"RB_TEST_2",								// AVP_LEADERBOARD_SCORE,
	"RB_TEST_3",								// AVP_LEADERBOARD_MATCHES,
	"RB_TEST_4",								// AVP_LEADERBOARD_MYSTATS,
	0,											// AVP_LEADERBOARD_INTERNAL,
};

static ELeaderboardSortMethod aeAVP_PC_LEADERBOARD_SORTORDER[AVP_NUM_LEADERBOARDS] = 
{
	k_ELeaderboardSortMethodDescending,			// AVP_LEADERBOARD_KILLS,
	k_ELeaderboardSortMethodDescending,			// AVP_LEADERBOARD_SCORE,
	k_ELeaderboardSortMethodDescending,			// AVP_LEADERBOARD_MATCHES,
	k_ELeaderboardSortMethodDescending,			// AVP_LEADERBOARD_MYSTATS,
	k_ELeaderboardSortMethodNone,				// AVP_LEADERBOARD_INTERNAL,
};

static ELeaderboardDisplayType aeAVP_PC_LEADERBOARD_DISPLAYTYPE[AVP_NUM_LEADERBOARDS] = 
{
	k_ELeaderboardDisplayTypeNumeric,			// AVP_LEADERBOARD_KILLS,
	k_ELeaderboardDisplayTypeNumeric,			// AVP_LEADERBOARD_SCORE,
	k_ELeaderboardDisplayTypeNumeric,			// AVP_LEADERBOARD_MATCHES,
	k_ELeaderboardDisplayTypeNumeric,			// AVP_LEADERBOARD_MYSTATS,
	k_ELeaderboardDisplayTypeNone,				// AVP_LEADERBOARD_INTERNAL,
};

const char* GetSteamStatFromStatID(u_int uStatID)
{
	return 0;
}

const char* Asura_PC_SteamworksLeaderboards::Project_GetBoardName(u_int uLeaderboardIndex)
{
	if (uLeaderboardIndex < AVP_NUM_LEADERBOARDS)
	{
		return aszAVP_PC_LEADERBOARD_BOARDNAME[uLeaderboardIndex];
	}
	return 0;
}

ELeaderboardSortMethod Asura_PC_SteamworksLeaderboards::Project_GetBoardSortType(u_int uLeaderboardIndex)
{
	if (uLeaderboardIndex < AVP_NUM_LEADERBOARDS)
	{
		return aeAVP_PC_LEADERBOARD_SORTORDER[uLeaderboardIndex];
	}
	return k_ELeaderboardSortMethodNone;
}

ELeaderboardDisplayType Asura_PC_SteamworksLeaderboards::Project_GetBoardDisplayType(u_int uLeaderboardIndex)
{
	if (uLeaderboardIndex < AVP_NUM_LEADERBOARDS)
	{
		return aeAVP_PC_LEADERBOARD_DISPLAYTYPE[uLeaderboardIndex];
	}
	return k_ELeaderboardDisplayTypeNone;
}

int Asura_PC_SteamworksLeaderboards::Project_GetScore(bool bDisconnectedEarly, u_int uMyGuid, u_int uLeaderboardIndex, u_int uColumn)
{
	Asura_Assert(uLeaderboardIndex < AVP_NUM_LEADERBOARDS, "invalid leaderboard");

	// use the client entity player info (which should exist on the server and contain the same results)
	const AVP_ClientEntity_PlayerInfo* pxPlayerInfo = AVP_ClientEntity_PlayerInfo::FindEntity(uMyGuid);
	Asura_Assert(pxPlayerInfo || bDisconnectedEarly, "failed to get player info to write stats");

	AVP_Multiplayer_PlayerScore xNullScore( pxPlayerInfo ? pxPlayerInfo->GetGuid() : ASURA_GUID_UNREGISTERED );
	const AVP_Multiplayer_PlayerScore& xScore = pxPlayerInfo ? pxPlayerInfo->GetPlayerScore() : xNullScore;

	const u_int uNumCols = Asura_Leaderboard_System::Project_GetNumLeaderboardColumns(uLeaderboardIndex);
	Asura_Assert(uColumn < uNumCols, "invalid column index");

	const u_int uStatID = AVP_Leaderboards::GetAssociatedStatID(uLeaderboardIndex, uColumn);
	const bool bIsAdditiveStat = AVP_Leaderboards::IsAdditiveStat(uStatID);
	if (bIsAdditiveStat)
	{
		const char* szSteamStat = GetSteamStatFromStatID(uStatID);
		ASURA_LB_DATAFORMAT eFormat = Asura_Leaderboard_System::Project_GetDataFormat(uLeaderboardIndex, uColumn);
		if (eFormat == ASURA_LB_DATAFORMAT_UINT)
		{
			int iOld = Asura_PC_SteamworksStats::GetIntStat(szSteamStat);
			int iNew = iOld + AVP_Leaderboards::GetStatResultById(uStatID, xScore);
			Asura_PC_SteamworksStats::SetStat(szSteamStat, iNew);
			return iNew;
		}
		else if (eFormat == ASURA_LB_DATAFORMAT_FLOAT)
		{
			float fOld = Asura_PC_SteamworksStats::GetFloatStat(szSteamStat);
			float fNew = fOld + static_cast<float>(AVP_Leaderboards::GetStatResultById(uStatID, xScore));
			Asura_PC_SteamworksStats::SetStat(szSteamStat, fNew);
			return Asura_Maths::FloatToInt_Near(fNew / Asura_PC_SteamworksLeaderboards::GetFixedpointFactor());
		}
		else
		{
			Asura_Assert(false, "unexpected stat format");
		}
	}
	else
	{
		// it's a computed stat
		switch (uStatID)
		{
			case AVP_STATID_KILLS_TO_DEATH_RATIO:
			{
				const u_int uKillsStatID = AVP_Leaderboards::GetAssociatedStatID(uLeaderboardIndex, 0);
				const char* szKillsSteamStat = GetSteamStatFromStatID(uKillsStatID);
				const u_int uDeathsCol = AVP_KILLS_TOTAL_DEATHS;
				const u_int uDeathsStatID = AVP_Leaderboards::GetAssociatedStatID(uLeaderboardIndex, uDeathsCol);
				const char* szDeathsSteamStat = GetSteamStatFromStatID(uDeathsStatID);
				// NY - 28 April 2009 - depending on when steam commits it's stats, this may need to change
				const u_int uTotalKills = Asura_PC_SteamworksStats::GetIntStat(szKillsSteamStat);
				const u_int uTotalDeaths = Asura_PC_SteamworksStats::GetIntStat(szDeathsSteamStat);
				// set ratio as float - use 1.0f if never died.
				// NY - 28 April 2009 - 1.0f seems wrong, as that means stats will go up when yuo die.
				// maybe use kills / 0.5f ?
				float fNew = uTotalDeaths ? 
					static_cast<float>(uTotalKills) / static_cast<float>(uTotalDeaths) : 1.0f;
				return Asura_Maths::FloatToInt_Near(fNew / Asura_PC_SteamworksLeaderboards::GetFixedpointFactor());
			}
			case AVP_STATID_WINNING_STREAK:
			{
				// TODO
				return 0;
			}
			default:
			{
				Asura_Assert(false, "unexpected computed stat");
				break;
			}
		}
	}
	return 0;
}


#endif // #ifdef ASURA_PC_SUPPORT_STEAMWORKS
#endif // #ifdef ASURA_SUPPORT_LEADERBOARDS
