#ifndef MR4TH_THREAD_H
#define MR4TH_THREAD_H

// TODO(allen): integrate this to the base layer

////////////////////////////////
// Thread Types

typedef struct TH_Thread  TH_Thread;
typedef struct TH_Mutex   TH_Mutex;
typedef struct TH_CondVar TH_CondVar;

typedef void TH_Func(void *param);

////////////////////////////////
// Thread Functions

MR4TH_SYMBOL void th_thread_create(TH_Func *func, void *param, TH_Thread *thread_out);
MR4TH_SYMBOL void th_thread_force_stop(TH_Thread *thread);

MR4TH_SYMBOL void th_mutex_init(TH_Mutex *mutex);
MR4TH_SYMBOL void th_mutex_release(TH_Mutex *mutex);
MR4TH_SYMBOL void th_mutex_wait_for_lock(TH_Mutex *mutex);
MR4TH_SYMBOL void th_mutex_unlock(TH_Mutex *mutex);

MR4TH_SYMBOL void th_condvar_init(TH_CondVar *cv);
MR4TH_SYMBOL void th_condvar_release(TH_CondVar *cv);
MR4TH_SYMBOL void th_condvar_wait_for_signal(TH_CondVar *cv, TH_Mutex *mutex);
MR4TH_SYMBOL void th_condvar_signal(TH_CondVar *cv);


/*******************************
**     Begin Thread Win32     **
*******************************/

#if OS_WINDOWS

#include <Windows.h>

struct TH_Thread{
    HANDLE thread;
};

struct TH_Mutex{
    CRITICAL_SECTION crit;
};

struct TH_CondVar{
    CONDITION_VARIABLE cv;
};

#endif

/*******************************
**      End Thread Win32      **
*******************************/


/*******************************
**     Begin Thread Linux     **
*******************************/

#if OS_LINUX

#include <pthread.h>

struct TH_Thread{
    pthread_t thread;
};

struct TH_Mutex{
    pthread_mutex_t mutex;
};

struct TH_CondVar{
    pthread_cond_t cv;
};

#endif

/*******************************
**      End Thread Linux      **
*******************************/


#endif //MR4TH_THREAD_H
