#ifndef __Thread__
#define __Thread__

#ifndef CORE_DLL 
    #ifdef CORE_BUILD
	    #define CORE_DLL __declspec(dllexport)
    #else
	    #define CORE_DLL __declspec(dllimport)
        #pragma comment(lib, "Core.lib")
    #endif
#endif


/**
 *   Encapsulation of OS-specific thread routines.
 *
 *   Derived classes must implement operator(), which defines the thread's actual codepath. 
 *
 *   Polite methods: pause(), unpause(), stop()
 *   Send a signal to the thread, asking it to perform an action.
 *   The thread may choose to ignore the signal, or to comply, but only when and how it sees fit.
 *
 *   Rude methods: suspend(), resume(), kill()
 *   Force the thread to immediately perform the requested action.
 *   Warning: these methods may cause adverse effects, and their use is generally not recommended.
 */

class CORE_DLL Thread {
public:
    static const unsigned long WAIT_INDEFINITELY = 0xFFFFFFFF;

    static const int LOW_PRIORITY = -2;
    static const int NORMAL_PRIORITY = 0;
    static const int HIGH_PRIORITY = 2;


	Thread(int priority = NORMAL_PRIORITY);
	virtual ~Thread();


    /**
     *  Starts the execution of the callee thread. The caller thread immediately resumes.
     */
    void start();


    /**
     *  The caller thread halts until the timeout is reached, or the callee thread finishes execution, 
     *  whichever comes first. By default, timeout is set to WAIT_INDEFINITELY, which will halt the 
     *  caller thread (potentially) indefinitely, until the callee thread finishes execution.
     *
     *  @param timeout      The timeout to wait, in miliseconds.
     */
    void join(unsigned long timeout = WAIT_INDEFINITELY);
    


    /**
     *  Politely ask the thread to pause execution.
     */
	void pause();

    /**
     *  Politely ask the thread to resume execution.
     */
    void unpause();

    /**
     *  Politely ask the thread to stop execution.
     */
	void stop();
    


    /**
     *  Force the thread to pause execution. Warning: this method may be dangerous.
     */
    void suspend();

    /** 
     *  Force the thread to resume execution. Warning: this method may be dangerous.
     */
    void resume();

    /**
     *  Force the thread to stop execution. Warning: this method may be dangerous.
     */
	void kill();


    int  getPriority();
    void setPriority(int priority);

protected:

    /**
     *  The actual codepath executed by the thread.
     */ 
	virtual void operator()() = 0;

    /**
     *  Helper method - returns true if the thread has been asked to stop.
     *  Derived classes should periodicaly check this, and respond accordingly.
     */
	bool canRun();

    /**
     *  Helper method - returns true if the thread is expected to be paused.
     *  Derived classes should periodicaly check this, and respond accordingly.
     */
    bool isPaused();


    void beginBackgroundMode();
    void endBackgroundMode();

private:

    /**
     *  Proxy function for dealing with OS-specific thread rutines. 
     *  Should never be called manually.
     */
	static unsigned long __stdcall entry(void* p);

	void*			_handle;
	unsigned long	_id;
    int             _priority;

	volatile bool	_canRun;
    volatile bool   _isPaused;
    volatile bool   _isSuspended;
};



#endif