#ifndef AVIFILE_MODULE_H
#define AVIFILE_MODULE_H
/*
extern "C" int STDCALL LoadLibraryA(const char*);
extern "C" void* STDCALL GetProcAddress(int, const char*);
extern "C" int STDCALL FreeLibrary(int);
*/

#include <list>
#include <string>
#include <videoencoder.h>

/*
 #define STORE_ALL \
 __asm__ __volatile__ ( \
 "push %ebx\n\t" \
 "push %ecx\n\t" \
 "push %edx\n\t" \
 "push %esi\n\t" \
 "push %edi\n\t": :)

 #define REST_ALL \
 __asm__ __volatile__ ( \
 "pop %edi\n\t" \
 "pop %esi\n\t" \
 "pop %edx\n\t" \
 "pop %ecx\n\t" \
 "pop %ebx\n\t": :)
 */
#define STORE_ALL
#define REST_ALL

class VideoCodecControl;
class VideoCodec;

#ifndef __WINE_WINDEF_H
typedef long __attribute__((__stdcall__)) (*DRIVERPROC)
    (unsigned long, unsigned int, unsigned int, long, long);
#endif

struct DRVR
{
    unsigned int     uDriverSignature;
    int              hDriverModule;
    DRIVERPROC       DriverProc;
    unsigned long    dwDriverID;
};

typedef int __attribute__((__stdcall__)) (*DRIVER_PROC)(int,int,int,int,int);

class Module
{
    VideoCodecControl& _parent;
    int forgotten;
    DRVR driver;
    int _refcount;
    DRIVER_PROC DriverProc;
    std::string _name;
public:
    int _handle;
    enum Mode {Compress, Decompress};
    Module(std::string name, VideoCodecControl& parent);//loads module
    ~Module();
    std::string Name() { return _name; }
//    int AddRef(){return _refcount++;}
    int CreateHandle(int compressor, Mode mode);
    int CloseHandle(int);
    void ForgetParent() { forgotten=1; }
//    int Release(); //decreases _refcount, unloads module and erases itself from control if needed
    int Message(int handle, int message, int arg1, int arg2);
};
    
class VideoCodecControl
{
friend class Module;
    std::list<Module*> _modules;
public:
    VideoCodecControl(){_modules.clear();}
    VideoCodec* Create(int compressor, const CodecInfo& info, Module::Mode mode);
    ~VideoCodecControl();
protected:
    void Erase(Module*);
};

extern VideoCodecControl control;

#endif // AVIFILE_MODULE_H
