/** @file asyncfileloader.cpp
* Implementation of UX's AsyncFileLoader class
* @headerfile asyncfileloader.h "asyncfileloader.h"
* @author Nick Beatty (nbeatty@ea.com)
* (c) 2011 Electronic Arts Inc.
*/
#include "asyncfileloader.h"

#include "eathread/eathread_thread.h"
#include "coreallocator/icoreallocatormacros.h"

namespace EA
{
	namespace Types
	{
		AsyncFileLoader::AsyncFileLoader(EA::Allocator::ICoreAllocator* pAllocator
										, EA::Types::AsyncFileHandler* pFileHandler
										, EA::Types::IFileHandlerCallbackIn pCallback
										, const char* pFileName)
			: mAllocator(pAllocator)
			, mFileHandler(pFileHandler)
			, mCallback(pCallback)
			, mResource(NULL)
			, mFileName(pAllocator, pFileName)
			, mThread(NULL)
		{
		}

		AsyncFileLoader::~AsyncFileLoader()
		{
			EndThread();
			mAllocator = NULL;
			mResource = NULL;
			mFileHandler = NULL;
			mCallback = NULL;
		}

		void AsyncFileLoader::StartLoad()
		{
			// \todo we can specify things like stack size, processor and priority here, right now we are just using defaults for everything except name
			static EA::Thread::ThreadParameters threadParms;
			threadParms.mpName = "EA::Types::AsyncFileLoader";

			mThread = CORE_NEW(mAllocator, "EA::Types::AsyncFileLoader::Thread", EA::Allocator::MEM_TEMP) EA::Thread::Thread();
			mThread->Begin(Run, this, &threadParms);
		}

		void AsyncFileLoader::EndThread()
		{
			if(mThread != NULL)
			{
				mThread->WaitForEnd();
				CORE_DELETE(mAllocator, mThread);
			}
		}

		/*static*/ intptr_t AsyncFileLoader::Run(void* pContext)
		{
			AsyncFileLoader* instance = static_cast<AsyncFileLoader *>(pContext);

			instance->mResource = static_cast<IFileHandler*>(instance->mFileHandler)->Load(instance->mAllocator, instance->mFileName.c_str());
			instance->mFileHandler->AsyncLoadComplete(instance);
			return 0;
		}
	}
}
