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

#ifndef EABASETYPESPLUS_ASYNCFILEHANDLER_H_
#define EABASETYPESPLUS_ASYNCFILEHANDLER_H_

#include "EABaseTypesPlus/ifilehandler.h"
#include "EABaseTypesPlus/vrefcountedica.h"

#include "EABaseTypes/autoref.h"
#include "EABaseTypes/string.h"

namespace EA
{
	namespace Allocator
	{
		class ICoreAllocator;
	}


	namespace Types
	{
		class Factory;
		class AsyncFileLoader;

		/*! @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 AsyncFileHandler : public VRefCountedICA<IFileHandler>
		{
		public:

			AsyncFileHandler(EA::Allocator::ICoreAllocator* allocator, const char* root);

			virtual ~AsyncFileHandler();

			/*!
			*	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(EA::Types::IFileHandlerCallbackIn callback, EA::Allocator::ICoreAllocator *allocator, const char* fileName);

			/*!
			*	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();

		protected:

			EA::RawString mRoot;

			friend class AsyncFileLoader;

			/*!
			*	Callback used to notify the IFileHandler that an asynchronous load has finished
			*	@param[in]	loader			Pointer to the loader that is finished
			*
			*   @sa EA::Types::AsyncFileLoader
			*	@attention This function should never be called except from an AsyncFileLoader instance
			*/
			virtual void AsyncLoadComplete(AsyncFileLoader* loader);

		private:

			AsyncFileHandler(const AsyncFileHandler& fileHandler);
			AsyncFileHandler& operator=(const AsyncFileHandler& rhs);

			struct AsyncFileHandlerImpl;

			AsyncFileHandlerImpl*			mImpl;
			EA::Allocator::ICoreAllocator*	mAllocator;
		};
	}
}

#endif /* EABASETYPESPLUS_ASYNCFILEHANDLER_H_ */
