//////////////////////////////////////////////////////////////////////////////
//
// Asura_PC_SteamworksLeaderboards.h
//
// Copyright (c) 2009 Rebellion. All rights reserved.
//
// Description:
//
//     Asura wrapper class for steam leaderboards
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ASURA_PC_STEAMWORKSLEADERBOARDS_H___
#define ASURA_PC_STEAMWORKSLEADERBOARDS_H___ 1


#ifdef ASURA_SUPPORT_LEADERBOARDS
#ifdef ASURA_PC_SUPPORT_STEAMWORKS

#include "steam/steam_api.h"

class Asura_PC_SteamworksLeaderboard_Writer;

class Asura_PC_SteamworksLeaderboards
{
public:
	static void StartWrite(bool bDisconnectedEarly, u_int uMyGuid);
	static bool UpdateWrite();

	static const char* Project_GetBoardName(u_int uLeaderboardIndex);
	static ELeaderboardSortMethod Project_GetBoardSortType(u_int uLeaderboardIndex);
	static ELeaderboardDisplayType Project_GetBoardDisplayType(u_int uLeaderboardIndex);

	static float GetFixedpointFactor() {return 10000.0f;}

private:
	static int Project_GetScore(bool bDisconnectedEarly, u_int uMyGuid, u_int uLeaderboardIndex, u_int uColumn);

	static Asura_PC_SteamworksLeaderboard_Writer** s_ppxLeaderboardWriters;
	static int** s_ppiScores;
	static u_int s_uNumLeaderboardsToWrite;
};

class Asura_PC_SteamworksLeaderboard_Writer
{
public:
	Asura_PC_SteamworksLeaderboard_Writer(u_int uLeaderboardIndex, int iScore, const int* piData, u_int uDataSize);
	~Asura_PC_SteamworksLeaderboard_Writer();

	bool IsWorking() const;
	bool IsErrored() const;

private:
	void OnFindLeaderboard( LeaderboardFindResult_t* pxFindLearderboardResult, bool bIOFailure );
	CCallResult<Asura_PC_SteamworksLeaderboard_Writer, LeaderboardFindResult_t> m_xSteamCBFindLeaderboard;

	void OnUploadScore( LeaderboardScoreUploaded_t *pxUploadResult, bool bIOFailure );
	CCallResult<Asura_PC_SteamworksLeaderboard_Writer, LeaderboardScoreUploaded_t> m_xSteamCBUploadScore;

	u_int m_uLeaderboardIndex;						// project index for the leaderboard
	SteamLeaderboard_t m_ulSteamLeaderboard;		// handle to the leaderboard we are displaying
	int m_iScore;
	const int* m_piData;
	u_int m_uDataSize;
	bool m_bSuccess;
	bool m_bError;
};


class Asura_PC_SteamworksLeaderboard_Reader
{
public:
	Asura_PC_SteamworksLeaderboard_Reader(u_int uLeaderboardIndex, bool bFriendsOnly);
	~Asura_PC_SteamworksLeaderboard_Reader();

	bool IsWorking() const;
	bool IsErrored() const;

	bool FetchRows(u_int uFirstRow);

	u_int GetNumRows() const;

	int GetRowRank(u_int uRow) const;
	const char* GetRowName(u_int uRow) const;
	int GetRowScore(u_int uRow) const;
	int GetRowData(u_int uRow, u_int uColumn) const;

	void ClearLoadedData();

	u_int GetTotalRows() const;

private:
	void OnFindLeaderboard( LeaderboardFindResult_t* pxFindLearderboardResult, bool bIOFailure );
	CCallResult<Asura_PC_SteamworksLeaderboard_Reader, LeaderboardFindResult_t> m_xSteamCBFindLeaderboard;

	void OnScoresDownloaded( LeaderboardScoresDownloaded_t* pxLeaderboardScoresDownloaded, bool bIOFailure );
	CCallResult<Asura_PC_SteamworksLeaderboard_Reader, LeaderboardScoresDownloaded_t> m_xSteamCBScoresDownloaded;

	void FindLeaderboard();

	void Fetch_Internal();

	enum STATE
	{
		STATE_VOID = 0,
		STATE_INITIALISING,
		STATE_LOADING,
		STATE_LOADED,
		STATE_ERROR,
		STATE_FOUND,
	};

	u_int m_uLeaderboardIndex;						// project index for the leaderboard
	SteamLeaderboard_t m_ulSteamLeaderboard;		// handle to the leaderboard we are displaying
	STATE m_eState;									// current state
	const bool m_bFriendsOnly;						// indicates friends only
	u_int m_uFirstRow;								// offset into main leaderboard
	LeaderboardEntry_t* m_pxScores;					// leaderboard entries from steam
	int** m_ppiData;								// extra column data
	u_int m_uNumRows;								// number of rows held
	u_int m_uNumColumns;							// number of columns of extra data held
	u_int m_uTotalRows;								// number of columns of extra data held
};

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

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ASURA_PC_STEAMWORKSLEADERBOARDS_H___
