/** @file points.h Basic prototypes and abstract classess for real time. */
#ifndef __POINTS_H__
#define __POINTS_H__

#include <stdio.h>

#include <wx/defs.h>
#include <wx/wxchar.h>


#define WRITE_BARIER	10000
#define READ_BARIER	100


class wxFrame;


/** Base class for all real time points. They should inherit ihis class. */
class Point
{
public:
  virtual double GetDouble(void) {return 0;};  ///< read double value
  virtual void SetDouble(double) {return;};    ///< write double value
};


/** double storage real time point */
class DoublePoint: public Point
{
protected:
  double d;			///< Internal value. It is accessible through GetDouble and SetDouble.

public:
  virtual double GetDouble(void) {return d;};
  virtual void SetDouble(double NewVal) {d=NewVal;return;};
};


/** byte storage real time point */
class BytePoint: public Point
{
protected:
  unsigned char b;  
public:
  virtual double GetDouble(void) {return b;};
  virtual void SetDouble(double NewVal) 
	{b = (NewVal<0) ? 0 : (unsigned char)NewVal; return;};
};


/** byte wrapper storage real time point */
class ByteWrapPoint: public Point
{
protected:
  unsigned char *b;
public:
  explicit ByteWrapPoint(unsigned char *IniB): b(IniB) {}

  virtual double GetDouble(void) {return (b==NULL)?0:*b;};	
  virtual void SetDouble(double NewVal) 
	{if(b) {*b = (NewVal<0) ? 0 : (unsigned char)NewVal;} return;};
};


/** word storage real time point */
class WordPoint: public Point
{
protected:
  unsigned w;
public:
  virtual double GetDouble(void) {return w;};
  virtual void SetDouble(double NewVal) 
	{w = (NewVal<0) ? 0 : (unsigned)NewVal; return;};

  virtual unsigned GetWord(void) {return w;};
  virtual void SetWord(unsigned NewVal) {w=NewVal; return;};
};


/////////////////////////////////////////////////////

/** Base class for Hardware drivers. Real HW driver should inherit this class. */
class AdDriver
{
public:
  virtual Point *GetInput(int) {return NULL;};  ///< Get n'th input point from driver.
  virtual Point *GetOutput(int) {return NULL;}; ///< Get n'th output point from driver.
  virtual void ResetDevice(void) {};		///< Allow resetting device from application.
  virtual ~AdDriver(void) {};
};


/** Class factory parent for HW drivers. All implemented HW drivers should have their factory. */
class BazeManagerDriver
{
private:static BazeManagerDriver *First; ///< start of chain of all managers
	BazeManagerDriver *Previous;     ///< previous manager in a queue
	BazeManagerDriver *Next;	 ///< next manager in a queue

protected:
        BazeManagerDriver(void);	 ///< no instance of this should be created by user

public: 
	virtual ~BazeManagerDriver();	 ///< destructor removes manager from a queue

        static BazeManagerDriver *GetFirst() {return First;} ///< Get first manager in a chain
        BazeManagerDriver *GetNext() const {return Next;}    ///< Get first manager in a chain

        virtual const char *GetName(void) const {return "??";}     ///< Get name of given driver - must be overriden in child object.
        virtual AdDriver *GetDriver(int Index, const char *Name=NULL);  ///< Return a proper driver - must be overriden in child object.
};


typedef enum
{
  vfUnspecified,
  vfCFCC,
  vfCLJR,
  vfCLPL,
  vfCPLA,
  vfDVCS,
  vfdvsd,
  vfDVSD,
  vfdvsl,
  vfdvhd,
  vfI420,
  vfIF09,
  vfIJPG,
  vfIYUV,
  vfMDVF,
  vfMJPG,
  vfPlum,
  vfRGB1,
  vfRGB24,
  vfRGB32,
  vfRGB4,
  vfRGB565,
  vfRGB555,
  vfRGB8,
  vfTVMJ,
  vfUYVY,
  vfYVYU,
  vfWAKE,
  vfYUYV,
  vfYUY2,
  vfYVU9,
  vfYV12,
  vfY211,
  vfY411,
  vfY41P,
  vfNV12,
  vfA2B10G10R10,
  vfA2R10G10B10,
  vfY422,
  vfV210,
  vfR16G16B16,
  vfB16G16R16,
  vfA16R16G16B16,
  vfA16B16G16R16,
  vfR210,
  vfAYUV
} EVideoFormats;


typedef struct
{
  unsigned char R;
  unsigned char G;
  unsigned char B;
} TCameraPalette;


class IMediaSample;


/** Abstract parent of camera driver. Real camera device should inherit this function. */
class CameraDevice
{
public: 
  CameraDevice(): UssageCount(0) {FrameCounter=0;pCameraPalette=NULL;}
  virtual ~CameraDevice();

  virtual int GetWidth(void) {return 0;}	///< Width of a camera image
  virtual int GetHeight(void) {return 0;}	///< Height of a camera image
  virtual int GetDepth(void) {return 0;}        ///< Number of planes 8-gray; 24-RGB mode
  virtual double GetFrameRate(int What=0) {return 0;} ///< Frames per second

  virtual bool Start(void) {return false;};	///< Start grabbing images
  virtual void Stop(bool StopGraph=false) {};	///< Stop grabbing images, optionally stop graph

  virtual const wxChar *GetName(void) const {return "??";} 
  
  virtual void *PeekImediaSample(int *Size, IMediaSample **tmpMediaSample) {return NULL;}
  virtual void ClearImediaSample(void) {}

  //virtual void GrabImage(void) {};		///< Obtain a new image.
  virtual void ChangeResolution(void) {};	///< allow user to set resolution from a dialog
  virtual void ShowPropertyPage(size_t hOwner=0) {};
  virtual void SelectVideoMode(int ReqWidth=320, int ReqHeight=240, int ReqDepth=-1, double NewFrameRate=0) 
	{ReqWidth=ReqWidth; ReqHeight=ReqHeight; ReqDepth=ReqDepth;};
  //virtual const unsigned char *GetBufferData(void) {return NULL;} ///< Get data, this abstract parent returns NULL.
  virtual unsigned GetLastScan(void) const {return 0;} 
  virtual void HookFrame(wxFrame *Frame2Hook) {}

  int UssageCount;
  volatile long FrameCounter;
  EVideoFormats VideoFormat;
  TCameraPalette *pCameraPalette;
};


/** Class factory parent for camera drivers. */
class BazeCameraDriver
{
private:static BazeCameraDriver *First; ///< start of chain of all managers
	BazeCameraDriver *Previous;     ///< previous manager in a queue
	BazeCameraDriver *Next;	        ///< next manager in a queue

protected:
        BazeCameraDriver(void);	        ///< no instance of this should be created by user

public:         
	virtual ~BazeCameraDriver();	///< destructor removes manager from a queue
        static BazeCameraDriver *GetFirst() {return First;} ///< Get first manager in a chain
        BazeCameraDriver *GetNext() const {return Next;}    ///< Get first manager in a chain

        virtual const wxChar *GetName(void) const {return "??";}    ///< Get name of given driver - must be overriden in child object.
        virtual CameraDevice *GetDriver(int Index, const char *Name=NULL);  ///< Return a proper driver - must be overriden in child object.

	enum
          {
	  ERASE_ALL = -1000  ///< To release all drivers use this as parameter od GetDriver function
	  };
};


#endif