/** @file ifilehandler.h
 *	Generic interface for file handling
 *	@author Chris Burns (cburns@ea.com)
 *
 *	(c) 2012 Electronic Arts Inc.
 */

#ifndef EABASETYPESPLUS_IFILEHANDLER_H_
#define EABASETYPESPLUS_IFILEHANDLER_H_

#include "EABaseTypes/autoref.h"
#include "EABaseTypesPlus/irefcounted.h"

namespace EA
{
	namespace Allocator
	{
		class ICoreAllocator;
	}

	namespace Types
	{
		EABASETYPES_FORWARD_DECLARATION(class, IFileResource)

		/*! @class	IFileResource ifilehandler.h	"ux_base/ifilehandler.h"
		*	@brief	Interface representing an in-memory file backed by
		*	some unknown implementation
		*	Allows direct access to a buffer containing the data
		*
		*	@todo	Needs full reference counting (AddRef()/Release()) for completeness
		*/
		class IFileResource : public virtual IRefCounted
		{
		public:

			/*!
			*	Retrieve a pointer to the data
			*	@return void*	A pointer to the data
			*	@todo			Shouldn't this be a const pointer?
			*/
			virtual void* GetData() = 0;

			/*!
			*	Retrieve the size of the data
			*	@return unsigned int The size of the data
			*/
			virtual unsigned int GetSize() const = 0;
		};

		EABASETYPES_FORWARD_DECLARATION(class, IFileHandlerCallback)

		/*! @class	IFileHandlerCallback ifilehandler.h	"ux_base/ifilehandler.h"
		*	@brief	Interface representing a ref counted callback interface for IFileHandler asynchronous loading
		*
		*	@sa	IFileHandler
		*/
		class IFileHandlerCallback : public virtual IRefCounted
		{
		public:

			/*!
			*	Called when the requested file load is complete
			*	@param[in]	fileResource The resource that was loaded
			*
			*/
			virtual void LoadComplete(IFileResourceIn fileResource) = 0;
		};

		EABASETYPES_FORWARD_DECLARATION(class, IFileHandler);
 
		/*! @class	IFileHandler ifilehandler.h	"ux_base/ifilehandler.h"
		*	@brief	Interface representing a generic file handler backed
		*	by some unknown implementation. Allows synchronous loading of 
		*	files as IFileResources
		*
		*	@todo	Needs support for streaming
		*/
		class IFileHandler : public IRefCounted
		{
		public:

			virtual ~IFileHandler() {}

			/*!
			*	Determine if a particular file exists
			*	@param[in]	allocator	The allocator to use for any resources allocated in the course of this operation
			*	@param[in]	fileName	The name of the file
			*	@return		bool		true if the file exists and can be opened, false otherwise
			*
			*	@attention		The allocator may or may not be used, it is there in case the implementation requires it for this operation
			*/
			virtual bool Exists(EA::Allocator::ICoreAllocator *allocator, const char* fileName) = 0;

			/*!
			*	Synchronously load a file as an IFileResource
			*	@param[in]	allocator		The allocator to use for any resources allocated in the course of this operation
			*	@param[in]	fileName		The name of the file
			*	@return		IFileResource	The file resource, or NULL if the load failed
			*
			*	@attention The allocator may or may not be used, it is there in case the implementation requires it for this operation
			*/
			virtual IFileResourceReturn Load(EA::Allocator::ICoreAllocator *allocator, const char* fileName) = 0;

			/*!
			*	Asynchronously load a file as an IFileResource
			*	@param[in]	callback		The callback instance to notify when the load is complete 
			*	@param[in]	allocator		The allocator to use for any resources allocated in the course of this operation
			*	@param[in]	fileName		The name of the file
			*	@return		IFileResource	The file resource, or NULL if the load failed
			*
			*	@sa	EA::Types::IFileHandlerCallback
			*/
			virtual void Load(IFileHandlerCallbackIn callback, EA::Allocator::ICoreAllocator *allocator, const char* fileName) = 0;

			/*!
			*	Update loop for processing completed asynchronous loads. 
			* 
			*	@attention This function should be called on a regular basis from the FE Sim thread
			*/
			virtual void Update() = 0;
		};
	}
}

#endif /* EABASETYPESPLUS_IFILEHANDLER_H_ */
