///////////////////////////////////////////////////////////////////////////////
//
// File: Asura_Xbox360_Storage.h
//
// Created by Martin G.Harris (25/2/2009)
// 
// Copyright (C) 2009 Rebellion, All Rights Reserved.
//
// Description:
//
//		Classes for reading/writing data to Xbox LIVE storage.
//
//		Currently the code supports per title per user storage (for local users);
//		global per title storage may work, but hasn't been tested;
//	    game clips for leaderboards haven't been implemented yet.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ASURA_XBOX360_STORAGE_H___
#define ASURA_XBOX360_STORAGE_H___ 1

// Includes
#include <Xbox.h>
#include <Xonline.h>

/////////////////////////////////////////////
// Asura_Xbox360_StorageTransactionManager //
/////////////////////////////////////////////
class Asura_Xbox360_StorageTransactionManager
{
public:
	// Note: XSTORAGE_FACILITY_PER_TITLE should work too, but is untested.
	Asura_Xbox360_StorageTransactionManager(XSTORAGE_FACILITY eFacility = XSTORAGE_FACILITY_PER_USER_TITLE);

	~Asura_Xbox360_StorageTransactionManager();

	// Download the file from the Xbox LIVE server asynchronously.
	// If the buffer is not large enough to hold the entire storage item then the download will fail.
	// Parameters: Name of file; memory buffer to store the data; and the size of this buffer.
	void GetDataAsync(const WCHAR* wszStoredItemName, void* pBuffer, u_int uBufferSize);

	// Upload the file to the Xbox LIVE server asynchronously.
	// The specified buffer must remain valid and unmodified until the upload operation completes.
	// Parameters: Name of file; memory containing the data; and the size of this data.
	void SetDataAsync(const WCHAR* wszStoredItemName, void* pData, u_int uDataSize);

	// Delete the file from the Xbox LIVE server asynchronously.
	// Only allowed for per user storage.
	// Parameters: Name of file to delete.
	void DeleteAsync(const WCHAR* wszStoredItemName);

	// Poll the IO data to see whether the operation has finished.
	// Return true when finished or if an error occurs.
	bool Update();

	// Result of the operation.
	bool HasErrorOccurred() const { return m_bError; }			// Has an error occurred?
	DWORD GetOperationResult() const { return m_dwResult; }		// Get the error code.
	DWORD GetNumBytesDownloaded() const { return m_xResults.dwBytesTotal; }	// Get total number of bytes downloaded.

protected:
	void BuildServerPath(const WCHAR* wszStoredItemName, WCHAR* wszServerPathName, DWORD* pdwServerPathLen);

	// Reset the transaction manager, cancel any in-progress transactions.
	void Reset();

	// Set the error condition.
	void SetError() { m_bError = true; }

private:
	u_int m_uUserIndex;					// user index in range [0,3]
	XSTORAGE_FACILITY m_eFacility;		// facility: global per title, or per title per user.
	
	XSTORAGE_DOWNLOAD_TO_MEMORY_RESULTS m_xResults;	// struct that stores the result of a download.
	XOVERLAPPED m_xOverlapped;			// struct that keeps track of the progress of the async operation.
	
	DWORD m_dwResult;					// Result of the operation (an error code).
	bool m_bError;						// Has an error occurred?
	bool m_bTransactionInProgress;		// Is a transaction in progress?
};

#endif //ASURA_XBOX360_STORAGE_H___

