#pragma once
#include "Utility.h"
#include <functional>

class UTILITYDLL CThread
{
friend UINT __cdecl MyThreadFunction(LPVOID lpParam);
private:
    HANDLE      m_threadHandle;
    CWinThread *m_pWinThread;
    DWORD       m_threadId;
    const char* m_threadName;
    CEvt        m_eventStarted;
    void _Run();
    bool bIsInterrupted;
public:
    CThread(const char* threadName, int nPrority = THREAD_PRIORITY_NORMAL);
    static CThread *Create(const char* threadName, std::function<void()> f, int nPrority = THREAD_PRIORITY_NORMAL);
    virtual ~CThread(void);
    bool         SetThreadPriority(int nPriority);
    virtual void Run() = 0;
    bool         Start();
    bool         Wait(DWORD dwMilliSeconds = INFINITE);
    bool         WaitStarted(DWORD dwMilliSeconds = INFINITE);
    DWORD        GetThreadId();
    HANDLE       GetThreadHandle();
    const char* GetName()
    {
        return m_threadName;
    }

    void        Interrupt();
    bool        IsInterrupted();
    void        SetThreadName(const char* threadName);
    static void SetThreadName(DWORD dwThreadID, const char* threadName);
};
