// Thread functionality
//------------------------------------------------------------------------------
#pragma once
#ifndef CORE_THREAD_H
#define CORE_THREAD_H

// Includes
//------------------------------------------------------------------------------
#include "Core/Env/Types.h"

#if defined( __APPLE__ ) || defined( __LINUX__ )
    #include <pthread.h> // TODO:C Look at moving this out of header
#endif

// Thread
//------------------------------------------------------------------------------
class Thread
{
public:
	#if defined( __WINDOWS__ )
		typedef uint32_t ThreadId;
		typedef void * ThreadHandle;
		typedef uint32_t (*ThreadEntryFunction)( void * param );

		#define INVALID_THREAD_HANDLE ( nullptr )
    #elif defined( __APPLE__ ) || defined( __LINUX__ )
        // TODO:MAC Implement Thread
        // TODO:Linux Implement Thread
        typedef pthread_t ThreadId;
        typedef void * ThreadHandle;
        typedef uint32_t (*ThreadEntryFunction)( void * param );
        // TODO:MAC check INVALID_THREAD_HANDLE
        // TODO:LINUX check INVALID_THREAD_HANDLE
        #define INVALID_THREAD_HANDLE ( nullptr )
    #else
        #error Unknown platform
	#endif

	static ThreadId GetCurrentThreadId();
	static bool IsThread( ThreadId threadId ) { return ( GetCurrentThreadId() == threadId ); }
	static bool IsMainThread() { return GetCurrentThreadId() == s_MainThreadId; }
    
    static void Sleep( int32_t ms );

	static ThreadHandle CreateThread( ThreadEntryFunction entryFunc,
									  const char * threadName = nullptr,
									  uint32_t stackSize = ( 64 * KILOBYTE ),
									  void * userData = nullptr
									);
	static int WaitForThread( ThreadHandle handle, uint32_t timeoutMS, bool & timedOut );
	static void CloseHandle( ThreadHandle h );

	static void SetThreadName( const char * name );

private:
	static ThreadId s_MainThreadId;
};

//------------------------------------------------------------------------------
#endif // CORE_THREAD_H
