Loader {
  public:
        Loader()        {};
        ~Loader()       {};

        void Setup( void );
        void Cleanup( void );

        void EnqueueRequest( LoaderQ *New );
        BOOL CancelRequest( void(*callback)(LoaderQ*), void *parameter, char *filename, DWORD fileoffset );

        void SetPause( BOOL state );

        BOOL Paused( void )             { return paused == PAUSED; };
        BOOL Stopped( void )    { return stopped; };

        BOOL LoaderQueueEmpty( void )   { return queueIsEmpty; };
        void WaitForLoader( void );
   void SetQueueStatusStoring (void);
   void SetQueueStatusSorting (void);
   QueueMode QueueStatus (void) {return queueStatus;};

  private:
        HANDLE  threadHandle;
        DWORD   threadID;

        char    WakeEventName[30];
        HANDLE  WakeEventHandle;

        CRITICAL_SECTION        cs_loaderQ;

        LoaderQ*        head;
        LoaderQ*        tail;

        volatile BOOL                           shutDown;
        volatile BOOL                           stopped;
        volatile LoaderPauseMode        paused;
        volatile BOOL                           queueIsEmpty;
        volatile QueueMode      queueStatus;

          DWORD        static  MainLoopWrapper( LPVOID myself );
          DWORD                   MainLoop( void );
          void SortLoaderQueue (void);
          LoaderQ*                GetNextRequest( void );

          void                    Enqueue( LoaderQ *New );
          void                    Dequeue( LoaderQ *Old );
         void        ReplaceHeadEntry (LoaderQ *New);
};



typedef struct LoaderQ {
        char                *filename;
        DWORD             fileoffset;
        void                   (*callback)( LoaderQ* );
        void                    *parameter;
        LoaderQ         *prev;          // Modified by loader
        LoaderQ         *next;          // Modified by loader
} LoaderQ;