
#ifndef _DCMVL_H_
#define _DCMVL_H_

// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the DCMVL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// DCMVL_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#ifdef DCMVL_EXPORTS
#define DCMVL_API __declspec(dllexport)
#else
#define DCMVL_API __declspec(dllimport)
#endif

// max ms that the app will wait for a mutex (or other event handle)
#define MAX_WAIT_TIME    500

#include <vfw.h>
#include "dbgnp.h"
#include "vidbo.h"
#include "filter.h"

// define some useful macros...
#ifndef DCM_MACROS
#define DCM_MACROS

// macros to safely cleanup pointers via release, free, or delete
#define ReleaseClean(x) if (x){ (x)->Release(); (x) = NULL; }
#define FreeClean(x) if (x){ free(x); x = NULL; }
#define DeleteClean(x) if (x){ delete x; x = NULL; }
#define DeleteCleanA(x) if (x){ delete[] x; x = NULL; }

// safely call a function via a pointer to a class instance
#define Call(x, y) if (x){ (x)->y; }

#endif

// verifies that a given source index is within valid bounds
#define SourceOK(x) (((x)>=0) && ((x)<MAX_CONCURRENT_VIDEO_STREAMS))

/////////////////////////////////////////////////////////////////////////////
// Video Handler Class

class DCMVL_API VideoHandler
{
public:
   VideoHandler();
   virtual ~VideoHandler();

   virtual void Handle(PFrameData pfd) = 0;
   virtual void OnStart(VIDEOINFOHEADER *pvih);
   virtual void OnStop();
   virtual void OnExit();
};

/////////////////////////////////////////////////////////////////////////////
// AVI Player Class

class DCMVL_API AviPlayer  
{
public:
	AviPlayer(VideoHandler *handler);
	virtual ~AviPlayer();
   
   int Play(PCHAR fname);
   void Stop();
   void Grab();
   int GetID();
   int IsFinished();

protected:

   VideoHandler *handler;
   volatile char bRun;
   int bFinished;
   LONGLONG duration;
   LONGLONG frame;
};

//////////////////////////////////////////////////////////
// Misc Library Functions

extern DCMVL_API int InitDCMVL(HINSTANCE hi, HWND hwnd);
extern DCMVL_API void CloseDCMVL();
extern DCMVL_API UINT GetVLVersion();
extern DCMVL_API int InitVideo(int iSource, int myData = 0);
extern DCMVL_API int InitVideo(int iSource, LPCWSTR fname, int myData = 0);
extern DCMVL_API int InitVideo2(int iSource, LPCTSTR fname, int myData = 0);
extern DCMVL_API int PlayVideo();
extern DCMVL_API int StopVideo(int *pNotify);
extern DCMVL_API int GetStreamFormat(int iSource, VIDEOINFOHEADER *vih);
extern DCMVL_API int SetStreamFormat(int iSource, VIDEOINFOHEADER *vih);
extern DCMVL_API REFERENCE_TIME FPS2RefTime(float fps);
extern DCMVL_API double RefTime2FPS(REFERENCE_TIME rt);
extern DCMVL_API int ShowSourceDialog(int iSource);
extern DCMVL_API int ShowStreamDialog(int iSource);

extern DCMVL_API int AviCreate(int iSource, PCHAR fname, int fps = 30);
extern DCMVL_API int AviCreate(int iSource, PCHAR fname, int vw, int vh, int fps = 30);
extern DCMVL_API int AviInit(int iSource = -1);
extern DCMVL_API int AviAddFrame(int iSource, BYTE *pFrame);
extern DCMVL_API int AviClose(int iSource = -1);
extern DCMVL_API int AviChooseCompressor(int iSource = -1);
extern DCMVL_API int AviSaveCodecData(PCHAR fname, int iSource);
extern DCMVL_API int AviLoadCodecData(PCHAR fname, int iSource = -1);
extern DCMVL_API int AviSetCodecData(PCOMPVARS pcv, int iSource = -1);
extern DCMVL_API int AviGetCodecData(PCOMPVARS pcv, int iSource);
extern DCMVL_API int AviGetDuration(int iSource, LONGLONG *pDuration);
extern DCMVL_API int AviSetRate(double rate);
extern DCMVL_API int AviGetPosition(LONGLONG *pPos, const GUID *pTimeFormat = NULL);
extern DCMVL_API int AviSetPosition(LONGLONG *pPos, const GUID *pTimeFormat = NULL);

extern DCMVL_API void SetupBMIHeader(BITMAPINFOHEADER *pbih,
                                     int vw, int vh, int bpp = 24, DWORD comp = BI_RGB);
extern DCMVL_API void UpdateBMIHeader(BITMAPINFOHEADER *pbih,
                                     int vw, int vh, int bpp = -1, DWORD comp = -1);
extern DCMVL_API LONGLONG GetFrame(int iSource);
extern DCMVL_API PFrameData GetImage(int iSource, int bBlock = TRUE);
extern DCMVL_API void ResetGraph();
extern DCMVL_API int GetSourceFilterNames(PCHAR names, int maxFilters, int maxStrLen);
extern DCMVL_API int GetSourceFilterName(int i, PCHAR name, int maxStrLen);

// debug functions to print various bits of information to the console
extern DCMVL_API int DumpGraphInfo();
extern DCMVL_API void DumpSourceFilters();
extern DCMVL_API void DumpSeekingCaps();
extern DCMVL_API void DumpFCC(DWORD x);
extern DCMVL_API void DumpBIH(BITMAPINFOHEADER *bih);

///////////////////////////////////////////////////////////
// Internal Library Functions

int GetMutex(HANDLE mutex, PCHAR friendlyName, int waitTime = MAX_WAIT_TIME);
void CloseAvi(int i);

///////////////////////////////////////////////////////////
// Global Variables for internal (to dll) use

extern HINSTANCE hinst;
extern HWND hwndParent;

///////////////////////////////////////////////////////////

#endif